Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 26198
b: refs/heads/master
c: 07db869
h: refs/heads/master
v: v3
  • Loading branch information
Linus Torvalds committed Apr 26, 2006
1 parent 4b4d716 commit 7e0caf3
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 42 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: 86a0f04387bfa814618bf0c2c8b203899c4fa5d2
refs/heads/master: 07db8696f5d484485dde77138ff87d19c8628a75
5 changes: 5 additions & 0 deletions trunk/Documentation/filesystems/sysfs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ class/
devices/
firmware/
net/
fs/

devices/ contains a filesystem representation of the device tree. It maps
directly to the internal kernel device tree, which is a hierarchy of
Expand All @@ -264,6 +265,10 @@ drivers/ contains a directory for each device driver that is loaded
for devices on that particular bus (this assumes that drivers do not
span multiple bus types).

fs/ contains a directory for some filesystems. Currently each
filesystem wanting to export attributes must create its own hierarchy
below fs/ (see ./fuse.txt for an example).


More information can driver-model specific features can be found in
Documentation/driver-model/.
Expand Down
35 changes: 20 additions & 15 deletions trunk/fs/fuse/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,24 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
}
}

void fuse_remove_background(struct fuse_conn *fc, struct fuse_req *req)
/*
* Called with sbput_sem held for read (request_end) or write
* (fuse_put_super). By the time fuse_put_super() is finished, all
* inodes belonging to background requests must be released, so the
* iputs have to be done within the locked region.
*/
void fuse_release_background(struct fuse_conn *fc, struct fuse_req *req)
{
list_del_init(&req->bg_entry);
iput(req->inode);
iput(req->inode2);
spin_lock(&fc->lock);
list_del(&req->bg_entry);
if (fc->num_background == FUSE_MAX_BACKGROUND) {
fc->blocked = 0;
wake_up_all(&fc->blocked_waitq);
}
fc->num_background--;
spin_unlock(&fc->lock);
}

/*
Expand Down Expand Up @@ -165,27 +175,22 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
wake_up(&req->waitq);
fuse_put_request(fc, req);
} else {
struct inode *inode = req->inode;
struct inode *inode2 = req->inode2;
struct file *file = req->file;
void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
req->end = NULL;
req->inode = NULL;
req->inode2 = NULL;
req->file = NULL;
if (!list_empty(&req->bg_entry))
fuse_remove_background(fc, req);
spin_unlock(&fc->lock);
down_read(&fc->sbput_sem);
if (fc->mounted)
fuse_release_background(fc, req);
up_read(&fc->sbput_sem);

/* fput must go outside sbput_sem, otherwise it can deadlock */
if (req->file)
fput(req->file);

if (end)
end(fc, req);
else
fuse_put_request(fc, req);

if (file)
fput(file);
iput(inode);
iput(inode2);
}
}

Expand Down
12 changes: 9 additions & 3 deletions trunk/fs/fuse/fuse_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,15 @@ struct fuse_conn {
/** waitq for blocked connection */
wait_queue_head_t blocked_waitq;

/** RW semaphore for exclusion with fuse_put_super() */
struct rw_semaphore sbput_sem;

/** The next unique request id */
u64 reqctr;

/** Mount is active */
unsigned mounted;

/** Connection established, cleared on umount, connection
abort and device release */
unsigned connected;
Expand Down Expand Up @@ -471,11 +477,11 @@ void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
void request_send_background(struct fuse_conn *fc, struct fuse_req *req);

/**
* Remove request from the the background list
* Release inodes and file associated with background request
*/
void fuse_remove_background(struct fuse_conn *fc, struct fuse_req *req);
void fuse_release_background(struct fuse_conn *fc, struct fuse_req *req);

/** Abort all requests */
/* Abort all requests */
void fuse_abort_conn(struct fuse_conn *fc);

/**
Expand Down
40 changes: 18 additions & 22 deletions trunk/fs/fuse/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,26 +204,17 @@ static void fuse_put_super(struct super_block *sb)
{
struct fuse_conn *fc = get_fuse_conn_super(sb);

down_write(&fc->sbput_sem);
while (!list_empty(&fc->background))
fuse_release_background(fc,
list_entry(fc->background.next,
struct fuse_req, bg_entry));

spin_lock(&fc->lock);
fc->mounted = 0;
fc->connected = 0;
while (!list_empty(&fc->background)) {
struct fuse_req *req = list_entry(fc->background.next,
struct fuse_req, bg_entry);
struct inode *inode = req->inode;
struct inode *inode2 = req->inode2;

/* File would hold a reference to vfsmount */
BUG_ON(req->file);
req->inode = NULL;
req->inode2 = NULL;
fuse_remove_background(fc, req);

spin_unlock(&fc->lock);
iput(inode);
iput(inode2);
spin_lock(&fc->lock);
}
spin_unlock(&fc->lock);
up_write(&fc->sbput_sem);
/* Flush all readers on this fs */
kill_fasync(&fc->fasync, SIGIO, POLL_IN);
wake_up_all(&fc->waitq);
Expand Down Expand Up @@ -395,6 +386,7 @@ static struct fuse_conn *new_conn(void)
INIT_LIST_HEAD(&fc->processing);
INIT_LIST_HEAD(&fc->io);
INIT_LIST_HEAD(&fc->background);
init_rwsem(&fc->sbput_sem);
kobj_set_kset_s(fc, connections_subsys);
kobject_init(&fc->kobj);
atomic_set(&fc->num_waiting, 0);
Expand Down Expand Up @@ -508,11 +500,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
if (file->f_op != &fuse_dev_operations)
return -EINVAL;

/* Setting file->private_data can't race with other mount()
instances, since BKL is held for ->get_sb() */
if (file->private_data)
return -EINVAL;

fc = new_conn();
if (!fc)
return -ENOMEM;
Expand Down Expand Up @@ -548,7 +535,14 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
if (err)
goto err_free_req;

/* Setting file->private_data can't race with other mount()
instances, since BKL is held for ->get_sb() */
err = -EINVAL;
if (file->private_data)
goto err_kobject_del;

sb->s_root = root_dentry;
fc->mounted = 1;
fc->connected = 1;
kobject_get(&fc->kobj);
file->private_data = fc;
Expand All @@ -563,6 +557,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)

return 0;

err_kobject_del:
kobject_del(&fc->kobj);
err_free_req:
fuse_request_free(init_req);
err_put_root:
Expand Down
8 changes: 7 additions & 1 deletion trunk/net/bridge/br_forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/if_vlan.h>
#include <linux/netfilter_bridge.h>
#include "br_private.h"

Expand All @@ -29,10 +30,15 @@ static inline int should_deliver(const struct net_bridge_port *p,
return 1;
}

static inline unsigned packet_length(const struct sk_buff *skb)
{
return skb->len - (skb->protocol == htons(ETH_P_8021Q) ? VLAN_HLEN : 0);
}

int br_dev_queue_push_xmit(struct sk_buff *skb)
{
/* drop mtu oversized packets except tso */
if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->tso_size)
if (packet_length(skb) > skb->dev->mtu && !skb_shinfo(skb)->tso_size)
kfree_skb(skb);
else {
#ifdef CONFIG_BRIDGE_NETFILTER
Expand Down

0 comments on commit 7e0caf3

Please sign in to comment.