Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 206375
b: refs/heads/master
c: a1d75f2
h: refs/heads/master
i:
  206373: bfa1996
  206371: 7fe66bf
  206367: 6518f98
v: v3
  • Loading branch information
Miklos Szeredi committed Jul 12, 2010
1 parent 276f162 commit fa80395
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7909b1c64078087ac153fb47a2f50793fe3ee7d0
refs/heads/master: a1d75f258230b75d46aecdf28b2e732413028863
88 changes: 88 additions & 0 deletions trunk/fs/fuse/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,91 @@ static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size,
return err;
}

static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
struct fuse_copy_state *cs)
{
struct fuse_notify_store_out outarg;
struct inode *inode;
struct address_space *mapping;
u64 nodeid;
int err;
pgoff_t index;
unsigned int offset;
unsigned int num;
loff_t file_size;
loff_t end;

err = -EINVAL;
if (size < sizeof(outarg))
goto out_finish;

err = fuse_copy_one(cs, &outarg, sizeof(outarg));
if (err)
goto out_finish;

err = -EINVAL;
if (size - sizeof(outarg) != outarg.size)
goto out_finish;

nodeid = outarg.nodeid;

down_read(&fc->killsb);

err = -ENOENT;
if (!fc->sb)
goto out_up_killsb;

inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
if (!inode)
goto out_up_killsb;

mapping = inode->i_mapping;
index = outarg.offset >> PAGE_CACHE_SHIFT;
offset = outarg.offset & ~PAGE_CACHE_MASK;
file_size = i_size_read(inode);
end = outarg.offset + outarg.size;
if (end > file_size) {
file_size = end;
fuse_write_update_size(inode, file_size);
}

num = outarg.size;
while (num) {
struct page *page;
unsigned int this_num;

err = -ENOMEM;
page = find_or_create_page(mapping, index,
mapping_gfp_mask(mapping));
if (!page)
goto out_iput;

this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset);
err = fuse_copy_page(cs, &page, offset, this_num, 0);
if (!err && offset == 0 && (num != 0 || file_size == end))
SetPageUptodate(page);
unlock_page(page);
page_cache_release(page);

if (err)
goto out_iput;

num -= this_num;
offset = 0;
index++;
}

err = 0;

out_iput:
iput(inode);
out_up_killsb:
up_read(&fc->killsb);
out_finish:
fuse_copy_finish(cs);
return err;
}

static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
unsigned int size, struct fuse_copy_state *cs)
{
Expand All @@ -1244,6 +1329,9 @@ static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
case FUSE_NOTIFY_INVAL_ENTRY:
return fuse_notify_inval_entry(fc, size, cs);

case FUSE_NOTIFY_STORE:
return fuse_notify_store(fc, size, cs);

default:
fuse_copy_finish(cs);
return -EINVAL;
Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/fuse/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ static int fuse_write_begin(struct file *file, struct address_space *mapping,
return 0;
}

static void fuse_write_update_size(struct inode *inode, loff_t pos)
void fuse_write_update_size(struct inode *inode, loff_t pos)
{
struct fuse_conn *fc = get_fuse_conn(inode);
struct fuse_inode *fi = get_fuse_inode(inode);
Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/fuse/fuse_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -748,4 +748,6 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
unsigned fuse_file_poll(struct file *file, poll_table *wait);
int fuse_dev_release(struct inode *inode, struct file *file);

void fuse_write_update_size(struct inode *inode, loff_t pos);

#endif /* _FS_FUSE_I_H */
13 changes: 12 additions & 1 deletion trunk/include/linux/fuse.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
*
* 7.14
* - add splice support to fuse device
*
* 7.15
* - add store notify
*/

#ifndef _LINUX_FUSE_H
Expand Down Expand Up @@ -68,7 +71,7 @@
#define FUSE_KERNEL_VERSION 7

/** Minor version number of this interface */
#define FUSE_KERNEL_MINOR_VERSION 14
#define FUSE_KERNEL_MINOR_VERSION 15

/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
Expand Down Expand Up @@ -260,6 +263,7 @@ enum fuse_notify_code {
FUSE_NOTIFY_POLL = 1,
FUSE_NOTIFY_INVAL_INODE = 2,
FUSE_NOTIFY_INVAL_ENTRY = 3,
FUSE_NOTIFY_STORE = 4,
FUSE_NOTIFY_CODE_MAX,
};

Expand Down Expand Up @@ -568,4 +572,11 @@ struct fuse_notify_inval_entry_out {
__u32 padding;
};

struct fuse_notify_store_out {
__u64 nodeid;
__u64 offset;
__u32 size;
__u32 padding;
};

#endif /* _LINUX_FUSE_H */

0 comments on commit fa80395

Please sign in to comment.