lkml.org 
[lkml]   [1997]   [Oct]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectUpdated 2.1.60 nfs client patch
The attached patch incorporates changes to nfs_file_close to flush
pending requests for all tasks at file close time. This fixes the
pending RPC request problem with make menuconfig.

I've left the test for pending requests in nfs_delete_inode, as there
may be some situations (e.g. interrupt signals) that prevent the
flushing at close time. In any event, the new code will protect against
the potential file corruption from reusing an inode with pending
requests.

The patch has been tested here with make menuconfig, kernel compiles,
bonnie, etc. and as far as I can determine is working very well.

Regards,
Bill--- linux-2.1.60/include/linux/nfs_fs.h.old Sun Oct 26 23:09:30 1997
+++ linux-2.1.60/include/linux/nfs_fs.h Wed Oct 29 00:28:27 1997
@@ -176,7 +176,7 @@
*/
extern int nfs_writepage(struct inode *, struct page *);
extern int nfs_check_error(struct inode *);
-extern int nfs_flush_dirty_pages(struct inode *, off_t, off_t);
+extern int nfs_flush_dirty_pages(struct inode *, pid_t, off_t, off_t);
extern int nfs_truncate_dirty_pages(struct inode *, unsigned long);
extern void nfs_invalidate_pages(struct inode *);
extern int nfs_updatepage(struct inode *, struct page *, const char *,
--- linux-2.1.60/fs/nfs/dir.c.old Sat Oct 25 07:43:18 1997
+++ linux-2.1.60/fs/nfs/dir.c Mon Oct 27 15:42:49 1997
@@ -333,7 +333,6 @@
{
struct nfs_dirent *cache = dircache;
int i;
- int freed = 0;

for (i = NFS_MAX_DIRCACHE; i--; cache++) {
if (sb && sb->s_dev != cache->dev)
@@ -347,14 +346,8 @@
if (cache->entry) {
free_page((unsigned long) cache->entry);
cache->entry = NULL;
- freed++;
}
}
-#ifdef NFS_PARANOIA
-if (freed)
-printk("nfs_invalidate_dircache_sb: freed %d pages from %s\n",
-freed, kdevname(sb->s_dev));
-#endif
}

/*
@@ -472,9 +465,9 @@
struct inode *inode;
int error = -EACCES;

+ nfs_invalidate_dircache(dir);
inode = nfs_fhget(dir->i_sb, fhandle, fattr);
if (inode) {
- nfs_invalidate_dircache(dir);
d_instantiate(dentry, inode);
nfs_renew_times(dentry);
error = 0;
@@ -638,14 +631,15 @@
{
struct qstr sqstr;
struct dentry *sdentry;
+ unsigned long hash;
int i, error;

sqstr.name = silly;
sqstr.len = slen;
- sqstr.hash = init_name_hash();
+ hash = init_name_hash();
for (i= 0; i < slen; i++)
- sqstr.hash = partial_name_hash(silly[i], sqstr.hash);
- sqstr.hash = end_name_hash(sqstr.hash);
+ hash = partial_name_hash(silly[i], hash);
+ sqstr.hash = end_name_hash(hash);
sdentry = d_lookup(parent, &sqstr);
if (!sdentry) {
sdentry = d_alloc(parent, &sqstr);
@@ -674,6 +668,11 @@
return -EIO; /* No need to silly rename. */
}

+#ifdef NFS_PARANOIA
+if (!dentry->d_inode)
+printk("NFS: silly-renaming %s/%s, negative dentry??\n",
+dentry->d_parent->d_name.name, dentry->d_name.name);
+#endif
if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
return -EBUSY; /* don't allow to unlink silly inode -- nope,
* think a bit: silly DENTRY, NOT inode --
@@ -729,20 +728,28 @@
error = nfs_proc_remove(NFS_SERVER(dir),
NFS_FH(dir), dentry->d_name.name);
if (error < 0)
- printk("NFS " __FUNCTION__ " failed (err = %d)\n",
- -error);
+ printk("NFS: can't silly-delete %s/%s, error=%d\n",
+ dentry->d_parent->d_name.name,
+ dentry->d_name.name, error);
if (dentry->d_inode) {
if (dentry->d_inode->i_nlink)
dentry->d_inode->i_nlink --;
- } else
+ } else {
+#ifdef NFS_PARANOIA
printk("nfs_silly_delete: negative dentry %s/%s\n",
dentry->d_parent->d_name.name,
dentry->d_name.name);
+#endif
+ }
nfs_invalidate_dircache(dir);
- /*
- * The dentry is unhashed, but we want to make it negative.
- */
- d_delete(dentry);
+ }
+ /*
+ * Check whether to expire the dentry ...
+ */
+ else {
+ unsigned long age = jiffies - dentry->d_time;
+ if (age > 10*HZ)
+ d_drop(dentry);
}
}

@@ -769,12 +776,22 @@
return -ENOENT;
}

+ error = -ENAMETOOLONG;
if (dentry->d_name.len > NFS_MAXNAMLEN)
- return -ENAMETOOLONG;
+ goto out;

error = nfs_sillyrename(dir, dentry);

if (error && error != -EBUSY) {
+#ifdef NFS_PARANOIA
+if (dentry->d_count > 1)
+printk("nfs_unlink: dentry %s/%s, d_count=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_count);
+if (dentry->d_inode && dentry->d_inode->i_count > 1)
+printk("nfs_unlink: dentry %s/%s, inode i_count=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_inode->i_count);
+#endif
+ /* N.B. should check for d_count > 1 and fail */
error = nfs_proc_remove(NFS_SERVER(dir),
NFS_FH(dir), dentry->d_name.name);
if (!error) {
@@ -785,11 +802,12 @@
d_delete(dentry);
}
}
-
+out:
return error;
}

-static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+static int
+nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
{
struct nfs_sattr sattr;
int error;
@@ -802,11 +820,12 @@
return -ENOENT;
}

+ error = -ENAMETOOLONG;
if (dentry->d_name.len > NFS_MAXNAMLEN)
- return -ENAMETOOLONG;
+ goto out;

if (strlen(symname) > NFS_MAXPATHLEN)
- return -ENAMETOOLONG;
+ goto out;

sattr.mode = S_IFLNK | S_IRWXUGO; /* SunOS 4.1.2 crashes without this! */
sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
@@ -827,10 +846,12 @@
*/
d_drop(dentry);
}
+out:
return error;
}

-static int nfs_link(struct inode *inode, struct inode *dir, struct dentry *dentry)
+static int
+nfs_link(struct inode *inode, struct inode *dir, struct dentry *dentry)
{
int error;

@@ -843,18 +864,37 @@
return -ENOENT;
}

+ error = -ENAMETOOLONG;
if (dentry->d_name.len > NFS_MAXNAMLEN)
- return -ENAMETOOLONG;
+ goto out;
+
+ /*
+ * The NFS server may want to use a new fileid for the link,
+ * so we can't reuse the existing inode for the new dentry.
+ * To force a new lookup after the link operation, we can just
+ * drop the new dentry, as long as it's not busy. (See above.)
+ */
+ error = -EBUSY;
+ if (dentry->d_count > 1) {
+#ifdef NFS_PARANOIA
+printk("nfs_link: dentry %s/%s busy, count=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_count);
+#endif
+ goto out;
+ }
+ d_drop(dentry);

error = nfs_proc_link(NFS_SERVER(inode), NFS_FH(inode), NFS_FH(dir),
dentry->d_name.name);
if (!error) {
nfs_invalidate_dircache(dir);
+#if 0
inode->i_count ++;
inode->i_nlink ++; /* no need to wait for nfs_refresh_inode() */
d_instantiate(dentry, inode);
- error = 0;
+#endif
}
+out:
return error;
}

@@ -875,16 +915,31 @@
* implementation that only depends on the dcache stuff instead of
* using the inode layer
*
+ * Unfortunately, things are a little more complicated than indicated
+ * above. The NFS server may decide to use a new fileid for the renamed
+ * file, so we can't link the new name to the old inode. Otherwise, the
+ * server might reuse the fileid after the old file has been removed,
+ * which would leave the new dentry holding an invalid fileid (possibly
+ * leading to file corruption). To handle this consider these cases:
+ * (1) within-directory:
+ * -- no problem, just use nfs_proc_rename
+ * (2) cross-directory, only one user for old and new dentry:
+ * -- drop both dentries to force new lookups, then use rename
+ * (3) cross-directory, multiple users for old, one user for new:
+ * -- drop new dentry, silly-rename old dentry and make a link
+ * (4) cross-directory, multiple users for new dentry:
+ * -- sorry, we're busy.
*/
static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry)
{
- int error;
-
- dfprintk(VFS, "NFS: rename(%x/%ld, %s -> %x/%ld, %s)\n",
- old_dir->i_dev, old_dir->i_ino, old_dentry->d_name.name,
- new_dir->i_dev, new_dir->i_ino, new_dentry->d_name.name);
+ int update = 1, error;

+#ifdef NFS_DEBUG_VERBOSE
+printk("nfs_rename: old %s/%s, count=%d, new %s/%s, count=%d\n",
+old_dentry->d_parent->d_name.name,old_dentry->d_name.name,old_dentry->d_count,
+new_dentry->d_parent->d_name.name,new_dentry->d_name.name,new_dentry->d_count);
+#endif
if (!old_dir || !S_ISDIR(old_dir->i_mode)) {
printk("nfs_rename: old inode is NULL or not a directory\n");
return -ENOENT;
@@ -895,37 +950,66 @@
return -ENOENT;
}

- if (old_dentry->d_name.len > NFS_MAXNAMLEN || new_dentry->d_name.len > NFS_MAXNAMLEN)
- return -ENAMETOOLONG;
-
- if (new_dir != old_dir) {
- error = nfs_sillyrename(old_dir, old_dentry);
-
- if (error == -EBUSY) {
- return -EBUSY;
- } else if (error == 0) { /* did silly rename stuff */
- error = nfs_link(old_dentry->d_inode,
- new_dir, new_dentry);
-
- return error;
- }
- /* no need for silly rename, proceed as usual */
+ error = -ENAMETOOLONG;
+ if (old_dentry->d_name.len > NFS_MAXNAMLEN ||
+ new_dentry->d_name.len > NFS_MAXNAMLEN)
+ goto out;
+ /*
+ * Examine the cases as noted above.
+ */
+ if (new_dir == old_dir)
+ goto simple_case;
+ error = -EBUSY;
+ if (new_dentry->d_count > 1) {
+#ifdef NFS_PARANOIA
+printk("nfs_rename: new dentry %s/%s busy, count=%d\n",
+new_dentry->d_parent->d_name.name, new_dentry->d_name.name,
+new_dentry->d_count);
+#endif
+ goto out;
}
+ d_drop(new_dentry);
+ if (old_dentry->d_count > 1)
+ goto complex_case;
+ d_drop(old_dentry);
+ update = 0;
+
+ /* no need for silly rename, proceed as usual */
+simple_case:
error = nfs_proc_rename(NFS_SERVER(old_dir),
NFS_FH(old_dir), old_dentry->d_name.name,
NFS_FH(new_dir), new_dentry->d_name.name);
- if (!error) {
- nfs_invalidate_dircache(old_dir);
- nfs_invalidate_dircache(new_dir);
- /*
- * We know these paths are still valid ...
- */
- nfs_renew_times(old_dentry);
- nfs_renew_times(new_dentry->d_parent);
+ if (error)
+ goto out;
+ nfs_invalidate_dircache(new_dir);
+ nfs_invalidate_dircache(old_dir);

- /* Update the dcache */
+ /* Update the dcache if needed */
+ if (update)
d_move(old_dentry, new_dentry);
- }
+ goto out;
+
+ /*
+ * We don't need to update the dcache in this case ... the
+ * new dentry has been dropped, and the old one silly-renamed.
+ */
+complex_case:
+ error = nfs_sillyrename(old_dir, old_dentry);
+ if (error)
+ goto out;
+ nfs_invalidate_dircache(old_dir);
+
+ error = nfs_link(old_dentry->d_inode, new_dir, new_dentry);
+ if (error)
+ goto out;
+ nfs_invalidate_dircache(new_dir);
+#ifdef NFS_PARANOIA
+printk("nfs_rename: dentry %s/%s linked to %s/%s, old count=%d\n",
+new_dentry->d_parent->d_name.name,new_dentry->d_name.name,
+old_dentry->d_parent->d_name.name,old_dentry->d_name.name,old_dentry->d_count);
+#endif
+
+out:
return error;
}

--- linux-2.1.60/fs/nfs/inode.c.old Sat Oct 25 07:43:18 1997
+++ linux-2.1.60/fs/nfs/inode.c Tue Oct 28 12:12:24 1997
@@ -91,16 +91,19 @@
static void
nfs_delete_inode(struct inode * inode)
{
+ int failed;
+
dprintk("NFS: delete_inode(%x/%ld)\n", inode->i_dev, inode->i_ino);
/*
* Flush out any pending write requests ...
*/
if (NFS_WRITEBACK(inode) != NULL) {
unsigned long timeout = jiffies + 5*HZ;
- printk("NFS: invalidating pending RPC requests\n");
+ printk("NFS: inode %ld, invalidating pending RPC requests\n",
+ inode->i_ino);
nfs_invalidate_pages(inode);
while (NFS_WRITEBACK(inode) != NULL && jiffies < timeout) {
- current->state = TASK_UNINTERRUPTIBLE;
+ current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies + HZ/10;
schedule();
}
@@ -109,8 +112,10 @@
printk("NFS: Arghhh, stuck RPC requests!\n");
}

- if (check_failed_request(inode))
- printk("NFS: inode had failed requests\n");
+ failed = check_failed_request(inode);
+ if (failed)
+ printk("NFS: inode %ld had %d failed requests\n",
+ inode->i_ino, failed);
clear_inode(inode);
}

--- linux-2.1.60/fs/nfs/write.c.old Sat Oct 25 07:43:18 1997
+++ linux-2.1.60/fs/nfs/write.c Wed Oct 29 12:19:10 1997
@@ -286,16 +286,17 @@
* Find a failed write request by pid
*/
static struct nfs_wreq *
-find_failed_request(struct inode *inode, pid_t pid, int all)
+find_failed_request(struct inode *inode, pid_t pid)
{
struct nfs_wreq *head, *req;

- if (!(req = head = nfs_failed_requests))
- return NULL;
- do {
- if (req->wb_inode == inode && (all || req->wb_pid == pid))
+ req = head = nfs_failed_requests;
+ while (req != NULL) {
+ if (req->wb_inode == inode && (pid == 0 || req->wb_pid == pid))
return req;
- } while ((req = WB_NEXT(req)) != head);
+ if ((req = WB_NEXT(req)) == head)
+ break;
+ }
return NULL;
}

@@ -335,7 +336,7 @@
struct nfs_wreq * req;
int found = 0;

- while ((req = find_failed_request(inode, 0, 1)) != NULL) {
+ while ((req = find_failed_request(inode, 0)) != NULL) {
remove_failed_request(req);
found++;
}
@@ -561,12 +562,13 @@
}

/* Create the write request. */
- if (!(req = create_write_request(inode, page, offset, count))) {
- status = -ENOBUFS;
+ status = -ENOBUFS;
+ req = create_write_request(inode, page, offset, count);
+ if (!req)
goto done;
- }

/* Copy data to page buffer. */
+ /* N.B. should check for fault here ... */
copy_from_user(page_addr + offset, buffer, count);

/* Schedule request */
@@ -593,6 +595,7 @@
transfer_page_lock(req);
/* rpc_execute(&req->wb_task); */
if (sync) {
+ /* N.B. if signalled, result not ready? */
wait_on_write_request(req);
if ((count = nfs_write_error(inode)) < 0)
status = count;
@@ -652,10 +655,20 @@

if (rqoffset < end && offset < rqend
&& (pid == 0 || req->wb_pid == pid)) {
- if (!WB_HAVELOCK(req))
+ if (!WB_HAVELOCK(req)) {
+#ifdef NFS_PARANOIA
+printk("nfs_flush: flushing inode=%ld, %d @ %lu\n",
+req->wb_inode->i_ino, req->wb_bytes, rqoffset);
+#endif
nfs_flush_request(req);
+ }
last = req;
}
+ } else {
+#ifdef NFS_PARANOIA
+printk("nfs_flush_pages: in progress inode=%ld, %d @ %lu\n",
+req->wb_inode->i_ino, req->wb_bytes, rqoffset);
+#endif
}
if (invalidate)
req->wb_flags |= NFS_WRITE_INVALIDATE;
@@ -668,6 +681,10 @@

/*
* Cancel all writeback requests, both pending and in progress.
+ *
+ * N.B. This doesn't seem to wake up the tasks -- are we sure
+ * they will eventually complete? Also, this could overwrite a
+ * failed status code from an already-completed task.
*/
static void
nfs_cancel_dirty(struct inode *inode, pid_t pid)
@@ -676,7 +693,8 @@

req = head = NFS_WRITEBACK(inode);
while (req != NULL) {
- if (req->wb_pid == pid) {
+ /* N.B. check for task already finished? */
+ if (pid == 0 || req->wb_pid == pid) {
req->wb_flags |= NFS_WRITE_CANCELLED;
rpc_exit(&req->wb_task, 0);
}
@@ -694,24 +712,30 @@
* this isn't used by the nlm module yet.
*/
int
-nfs_flush_dirty_pages(struct inode *inode, off_t offset, off_t len)
+nfs_flush_dirty_pages(struct inode *inode, pid_t pid, off_t offset, off_t len)
{
struct nfs_wreq *last = NULL;
- int result = 0;
+ int result = 0, cancel = 0;

dprintk("NFS: flush_dirty_pages(%x/%ld for pid %d %ld/%ld)\n",
inode->i_dev, inode->i_ino, current->pid,
offset, len);

+ if (IS_SOFT && signalled()) {
+ nfs_cancel_dirty(inode, pid);
+ cancel = 1;
+ }
+
for (;;) {
if (IS_SOFT && signalled()) {
- nfs_cancel_dirty(inode, current->pid);
+ if (!cancel)
+ nfs_cancel_dirty(inode, pid);
result = -ERESTARTSYS;
break;
}

- /* Flush all pending writes for this pid and file region */
- last = nfs_flush_pages(inode, current->pid, offset, len, 0);
+ /* Flush all pending writes for the pid and file region */
+ last = nfs_flush_pages(inode, pid, offset, len, 0);
if (last == NULL)
break;
wait_on_write_request(last);
@@ -724,7 +748,7 @@
* Flush out any pending write requests and flag that they be discarded
* after the write is complete.
*
- * This function is called from nfs_revalidate_inode just before it calls
+ * This function is called from nfs_refresh_inode just before it calls
* invalidate_inode_pages. After nfs_flush_pages returns, we can be sure
* that all dirty pages are locked, so that invalidate_inode_pages does
* not throw away any dirty pages.
@@ -780,7 +804,7 @@
dprintk("nfs: checking for write error inode %04x/%ld\n",
inode->i_dev, inode->i_ino);

- req = find_failed_request(inode, current->pid, 0);
+ req = find_failed_request(inode, current->pid);
if (req) {
dprintk("nfs: write error %d inode %04x/%ld\n",
req->wb_task.tk_status, inode->i_dev, inode->i_ino);
@@ -869,7 +893,7 @@
* application by adding the request to the failed
* requests list.
*/
- if (find_failed_request(inode, req->wb_pid, 0))
+ if (find_failed_request(inode, req->wb_pid))
status = 0;
clear_bit(PG_uptodate, &page->flags);
} else if (!WB_CANCELLED(req)) {
--- linux-2.1.60/fs/nfs/file.c.old Sat Oct 25 07:43:18 1997
+++ linux-2.1.60/fs/nfs/file.c Wed Oct 29 11:03:33 1997
@@ -83,53 +83,77 @@
# define IS_SWAPFILE(inode) (0)
#endif

-
+/*
+ * Flush all dirty pages, and check for write errors.
+ *
+ * Note that since the file close operation is called only by the
+ * _last_ process to close the file, we need to flush _all_ dirty
+ * pages. This also means that there is little sense in checking
+ * for errors for this specific process -- we should probably just
+ * clear all errors.
+ */
static int
nfs_file_close(struct inode *inode, struct file *file)
{
- int status;
+ int status, error;

dfprintk(VFS, "nfs: close(%x/%ld)\n", inode->i_dev, inode->i_ino);

- if ((status = nfs_flush_dirty_pages(inode, 0, 0)) < 0)
- return status;
- return nfs_write_error(inode);
+ status = nfs_flush_dirty_pages(inode, 0, 0, 0);
+ error = nfs_write_error(inode);
+ if (!status)
+ status = error;
+ return status;
}

static ssize_t
nfs_file_read(struct file * file, char * buf, size_t count, loff_t *ppos)
{
struct inode * inode = file->f_dentry->d_inode;
- int status;
+ ssize_t result;

dfprintk(VFS, "nfs: read(%x/%ld, %lu@%lu)\n",
inode->i_dev, inode->i_ino, count,
(unsigned long) *ppos);

- if ((status = nfs_revalidate_inode(NFS_SERVER(inode), inode)) < 0)
- return status;
- return generic_file_read(file, buf, count, ppos);
+ result = nfs_revalidate_inode(NFS_SERVER(inode), inode);
+ if (!result)
+ result = generic_file_read(file, buf, count, ppos);
+ return result;
}

static int
nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
{
- int status;
struct inode *inode = file->f_dentry->d_inode;
+ int status;

dfprintk(VFS, "nfs: mmap(%x/%ld)\n", inode->i_dev, inode->i_ino);

- if ((status = nfs_revalidate_inode(NFS_SERVER(inode), inode)) < 0)
- return status;
- return generic_file_mmap(file, vma);
+ status = nfs_revalidate_inode(NFS_SERVER(inode), inode);
+ if (!status)
+ status = generic_file_mmap(file, vma);
+ return status;
}

-static int nfs_fsync(struct file *file, struct dentry *dentry)
+/*
+ * Flush any dirty pages for this process, and check for write errors.
+ * The return status from this call provides a reliable indication of
+ * whether any write errors occurred for this process.
+ */
+static int
+nfs_fsync(struct file *file, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
+ int status, error;
+
dfprintk(VFS, "nfs: fsync(%x/%ld)\n", inode->i_dev, inode->i_ino);

- return nfs_flush_dirty_pages(inode, 0, 0);
+ status = nfs_flush_dirty_pages(inode, current->pid, 0, 0);
+ error = nfs_write_error(inode);
+ if (!status)
+ status = error;
+ return status;
}

/*
@@ -139,7 +163,7 @@
nfs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
struct inode * inode = file->f_dentry->d_inode;
- int result;
+ ssize_t result;

dfprintk(VFS, "nfs: write(%x/%ld (%d), %lu@%lu)\n",
inode->i_dev, inode->i_ino, inode->i_count,
@@ -153,21 +177,26 @@
printk("NFS: attempt to write to active swap file!\n");
return -EBUSY;
}
- if ((result = nfs_revalidate_inode(NFS_SERVER(inode), inode)) < 0)
- return result;
+ result = nfs_revalidate_inode(NFS_SERVER(inode), inode);
+ if (result)
+ goto out;
+
+ /* N.B. This should be impossible now -- inodes can't change mode */
if (!S_ISREG(inode->i_mode)) {
printk("nfs_file_write: write to non-file, mode %07o\n",
inode->i_mode);
return -EINVAL;
}
- if (count <= 0)
- return 0;
-
- /* Return error from previous async call */
- if ((result = nfs_write_error(inode)) < 0)
- return result;
-
- return generic_file_write(file, buf, count, ppos);
+ result = count;
+ if (!count)
+ goto out;
+
+ /* Check for an error from a previous async call */
+ result = nfs_write_error(inode);
+ if (!result)
+ result = generic_file_write(file, buf, count, ppos);
+out:
+ return result;
}

/*
@@ -176,15 +205,15 @@
int
nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
{
+ struct inode * inode = filp->f_dentry->d_inode;
int status;
- struct inode * inode;

dprintk("NFS: nfs_lock(f=%4x/%ld, t=%x, fl=%x, r=%ld:%ld)\n",
- filp->f_dentry->d_inode->i_dev, filp->f_dentry->d_inode->i_ino,
+ inode->i_dev, inode->i_ino,
fl->fl_type, fl->fl_flags,
fl->fl_start, fl->fl_end);

- if (!(inode = filp->f_dentry->d_inode))
+ if (!inode)
return -EINVAL;

/* No mandatory locks over NFS */
@@ -209,7 +238,7 @@
* been killed by a signal, that is). */
if (cmd == F_SETLK && fl->fl_type == F_UNLCK
&& !signal_pending(current)) {
- status = nfs_flush_dirty_pages(inode,
+ status = nfs_flush_dirty_pages(inode, current->pid,
fl->fl_start, fl->fl_end == NLM_OFFSET_MAX? 0 :
fl->fl_end - fl->fl_start + 1);
if (status < 0)
\
 
 \ /
  Last update: 2005-03-22 13:40    [W:0.054 / U:0.136 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site