aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2006-10-17 18:17:58 +0000
committerMiklos Szeredi <miklos@szeredi.hu>2006-10-17 18:17:58 +0000
commitdcfb82145049d85b6b859d906fa94cd2f0900091 (patch)
tree2f7afa0fe41b76079551964614055c61f329ed15 /kernel
parent12e5c98d0606df60ee198de0f394f0c5d4c7caaa (diff)
downloadlibfuse-dcfb82145049d85b6b859d906fa94cd2f0900091.tar.gz
sync + update FAQ/Filesystems
Diffstat (limited to 'kernel')
-rw-r--r--kernel/dir.c26
-rw-r--r--kernel/file.c12
2 files changed, 20 insertions, 18 deletions
diff --git a/kernel/dir.c b/kernel/dir.c
index b7305a2..ecf38fb 100644
--- a/kernel/dir.c
+++ b/kernel/dir.c
@@ -150,13 +150,9 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
return 0;
parent = dget_parent(entry);
- if (!parent->d_inode) {
- dput(parent);
- return 0;
- }
fuse_lookup_init(req, parent->d_inode, entry, &outarg);
- dput(parent);
request_send(fc, req);
+ dput(parent);
err = req->out.h.error;
/* Zero nodeid is same as -ENOENT */
if (!err && !outarg.nodeid)
@@ -196,11 +192,16 @@ static int valid_mode(int m)
S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
}
+/*
+ * Add a directory inode to a dentry, ensuring that no other dentry
+ * refers to this inode. Called with fc->inst_mutex.
+ */
static struct dentry *fuse_d_add_directory(struct dentry *entry,
struct inode *inode)
{
struct dentry *alias = d_find_alias(inode);
if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
+ /* This tries to shrink the subtree below alias */
fuse_invalidate_entry(alias);
dput(alias);
if (!list_empty(&inode->i_dentry))
@@ -1000,13 +1001,14 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
static void fuse_vmtruncate(struct inode *inode, loff_t offset)
{
struct fuse_conn *fc = get_fuse_conn(inode);
- loff_t origsize = i_size_read(inode);
- if (origsize != offset) {
- spin_lock(&fc->lock);
- i_size_write(inode, offset);
- spin_unlock(&fc->lock);
- }
- if (origsize > offset) {
+ int need_trunc;
+
+ spin_lock(&fc->lock);
+ need_trunc = inode->i_size > offset;
+ i_size_write(inode, offset);
+ spin_unlock(&fc->lock);
+
+ if (need_trunc) {
struct address_space *mapping = inode->i_mapping;
unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
truncate_inode_pages(mapping, offset);
diff --git a/kernel/file.c b/kernel/file.c
index 6f941ad..6cf71f3 100644
--- a/kernel/file.c
+++ b/kernel/file.c
@@ -495,11 +495,10 @@ static int fuse_commit_write(struct file *file, struct page *page,
err = -EIO;
if (!err) {
pos += count;
- if (pos > i_size_read(inode)) {
- spin_lock(&fc->lock);
+ spin_lock(&fc->lock);
+ if (pos > inode->i_size)
i_size_write(inode, pos);
- spin_unlock(&fc->lock);
- }
+ spin_unlock(&fc->lock);
if (offset == 0 && to == PAGE_CACHE_SIZE) {
clear_page_dirty(page);
@@ -604,9 +603,10 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
}
fuse_put_request(fc, req);
if (res > 0) {
- if (write && pos > i_size_read(inode)) {
+ if (write) {
spin_lock(&fc->lock);
- i_size_write(inode, pos);
+ if (pos > inode->i_size)
+ i_size_write(inode, pos);
spin_unlock(&fc->lock);
}
*ppos = pos;