Revision a7ba4bf5e7ff6bfe83e41c748b77b49297c1b5d9 authored by Linus Torvalds on 02 July 2015, 18:21:26 UTC, committed by Linus Torvalds on 02 July 2015, 18:21:26 UTC
Pull fuse updates from Miklos Szeredi:
 "This is the start of improving fuse scalability.

  An input queue and a processing queue is split out from the monolithic
  fuse connection, each of those having their own spinlock.  The end of
  the patchset adds the ability to clone a fuse connection.  This means,
  that instead of having to read/write requests/answers on a single fuse
  device fd, the fuse daemon can have multiple distinct file descriptors
  open.  Each of those can be used to receive requests and send answers,
  currently the only constraint is that a request must be answered on
  the same fd as it was read from.

  This can be extended further to allow binding a device clone to a
  specific CPU or NUMA node.

  Based on a patchset by Srinivas Eeda and Ashish Samant.  Thanks to
  Ashish for the review of this series"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: (40 commits)
  fuse: update MAINTAINERS entry
  fuse: separate pqueue for clones
  fuse: introduce per-instance fuse_dev structure
  fuse: device fd clone
  fuse: abort: no fc->lock needed for request ending
  fuse: no fc->lock for pqueue parts
  fuse: no fc->lock in request_end()
  fuse: cleanup request_end()
  fuse: request_end(): do once
  fuse: add req flag for private list
  fuse: pqueue locking
  fuse: abort: group pqueue accesses
  fuse: cleanup fuse_dev_do_read()
  fuse: move list_del_init() from request_end() into callers
  fuse: duplicate ->connected in pqueue
  fuse: separate out processing queue
  fuse: simplify request_wait()
  fuse: no fc->lock for iqueue parts
  fuse: allow interrupt queuing without fc->lock
  fuse: iqueue locking
  ...
2 parent s a611fb7 + 0a30f61
Raw File
ncp_fs_sb.h
/*
 *  ncp_fs_sb.h
 *
 *  Copyright (C) 1995, 1996 by Volker Lendecke
 *
 */

#ifndef _NCP_FS_SB
#define _NCP_FS_SB

#include <linux/types.h>
#include <linux/ncp_mount.h>
#include <linux/net.h>
#include <linux/mutex.h>
#include <linux/backing-dev.h>
#include <linux/workqueue.h>

#define NCP_DEFAULT_OPTIONS 0		/* 2 for packet signatures */

struct sock;

struct ncp_mount_data_kernel {
	unsigned long    flags;		/* NCP_MOUNT_* flags */
	unsigned int	 int_flags;	/* internal flags */
#define NCP_IMOUNT_LOGGEDIN_POSSIBLE	0x0001
	kuid_t		 mounted_uid;	/* Who may umount() this filesystem? */
	struct pid      *wdog_pid;	/* Who cares for our watchdog packets? */
	unsigned int     ncp_fd;	/* The socket to the ncp port */
	unsigned int     time_out;	/* How long should I wait after
					   sending a NCP request? */
	unsigned int     retry_count;	/* And how often should I retry? */
	unsigned char	 mounted_vol[NCP_VOLNAME_LEN + 1];
	kuid_t		 uid;
	kgid_t		 gid;
	umode_t		 file_mode;
	umode_t		 dir_mode;
	int		 info_fd;
};

struct ncp_server {
	struct rcu_head rcu;
	struct ncp_mount_data_kernel m;	/* Nearly all of the mount data is of
					   interest for us later, so we store
					   it completely. */

	__u8 name_space[NCP_NUMBER_OF_VOLUMES + 2];

	struct socket *ncp_sock;/* ncp socket */
	struct socket *info_sock;

	u8 sequence;
	u8 task;
	u16 connection;		/* Remote connection number */

	u8 completion;		/* Status message from server */
	u8 conn_status;		/* Bit 4 = 1 ==> Server going down, no
				   requests allowed anymore.
				   Bit 0 = 1 ==> Server is down. */

	int buffer_size;	/* Negotiated bufsize */

	int reply_size;		/* Size of last reply */

	int packet_size;
	unsigned char *packet;	/* Here we prepare requests and
				   receive replies */
	unsigned char *txbuf;	/* Storage for current request */
	unsigned char *rxbuf;	/* Storage for reply to current request */

	int lock;		/* To prevent mismatch in protocols. */
	struct mutex mutex;

	int current_size;	/* for packet preparation */
	int has_subfunction;
	int ncp_reply_size;

	int root_setuped;
	struct mutex root_setup_lock;

	/* info for packet signing */
	int sign_wanted;	/* 1=Server needs signed packets */
	int sign_active;	/* 0=don't do signing, 1=do */
	char sign_root[8];	/* generated from password and encr. key */
	char sign_last[16];	

	/* Authentication info: NDS or BINDERY, username */
	struct {
		int	auth_type;
		size_t	object_name_len;
		void*	object_name;
		int	object_type;
	} auth;
	/* Password info */
	struct {
		size_t	len;
		void*	data;
	} priv;
	struct rw_semaphore auth_rwsem;

	/* nls info: codepage for volume and charset for I/O */
	struct nls_table *nls_vol;
	struct nls_table *nls_io;

	/* maximum age in jiffies */
	atomic_t dentry_ttl;

	/* miscellaneous */
	unsigned int flags;

	spinlock_t requests_lock;	/* Lock accesses to tx.requests, tx.creq and rcv.creq when STREAM mode */

	void (*data_ready)(struct sock* sk);
	void (*error_report)(struct sock* sk);
	void (*write_space)(struct sock* sk);	/* STREAM mode only */
	struct {
		struct work_struct tq;		/* STREAM/DGRAM: data/error ready */
		struct ncp_request_reply* creq;	/* STREAM/DGRAM: awaiting reply from this request */
		struct mutex creq_mutex;	/* DGRAM only: lock accesses to rcv.creq */

		unsigned int state;		/* STREAM only: receiver state */
		struct {
			__u32 magic __packed;
			__u32 len __packed;
			__u16 type __packed;
			__u16 p1 __packed;
			__u16 p2 __packed;
			__u16 p3 __packed;
			__u16 type2 __packed;
		} buf;				/* STREAM only: temporary buffer */
		unsigned char* ptr;		/* STREAM only: pointer to data */
		size_t len;			/* STREAM only: length of data to receive */
	} rcv;
	struct {
		struct list_head requests;	/* STREAM only: queued requests */
		struct work_struct tq;		/* STREAM only: transmitter ready */
		struct ncp_request_reply* creq;	/* STREAM only: currently transmitted entry */
	} tx;
	struct timer_list timeout_tm;		/* DGRAM only: timeout timer */
	struct work_struct timeout_tq;		/* DGRAM only: associated queue, we run timers from process context */
	int timeout_last;			/* DGRAM only: current timeout length */
	int timeout_retries;			/* DGRAM only: retries left */
	struct {
		size_t len;
		__u8 data[128];
	} unexpected_packet;
	struct backing_dev_info bdi;
};

extern void ncp_tcp_rcv_proc(struct work_struct *work);
extern void ncp_tcp_tx_proc(struct work_struct *work);
extern void ncpdgram_rcv_proc(struct work_struct *work);
extern void ncpdgram_timeout_proc(struct work_struct *work);
extern void ncpdgram_timeout_call(unsigned long server);
extern void ncp_tcp_data_ready(struct sock* sk);
extern void ncp_tcp_write_space(struct sock* sk);
extern void ncp_tcp_error_report(struct sock* sk);

#define NCP_FLAG_UTF8	1

#define NCP_CLR_FLAG(server, flag)	((server)->flags &= ~(flag))
#define NCP_SET_FLAG(server, flag)	((server)->flags |= (flag))
#define NCP_IS_FLAG(server, flag)	((server)->flags & (flag))

static inline int ncp_conn_valid(struct ncp_server *server)
{
	return ((server->conn_status & 0x11) == 0);
}

static inline void ncp_invalidate_conn(struct ncp_server *server)
{
	server->conn_status |= 0x01;
}

#endif
back to top