fs/dlm/lowcomms.c

Source file repositories/reference/linux-study-clean/fs/dlm/lowcomms.c

File Facts

System
Linux kernel
Corpus path
fs/dlm/lowcomms.c
Extension
.c
Size
48779 bytes
Lines
1988
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct connection {
	struct socket *sock;	/* NULL if not connected */
	uint32_t nodeid;	/* So we know who we are in the list */
	/* this semaphore is used to allow parallel recv/send in read
	 * lock mode. When we release a sock we need to held the write lock.
	 *
	 * However this is locking code and not nice. When we remove the
	 * othercon handling we can look into other mechanism to synchronize
	 * io handling to call sock_release() at the right time.
	 */
	struct rw_semaphore sock_lock;
	unsigned long flags;
#define CF_APP_LIMITED 0
#define CF_RECV_PENDING 1
#define CF_SEND_PENDING 2
#define CF_RECV_INTR 3
#define CF_IO_STOP 4
#define CF_IS_OTHERCON 5
	struct list_head writequeue;  /* List of outgoing writequeue_entries */
	spinlock_t writequeue_lock;
	int retries;
	struct hlist_node list;
	/* due some connect()/accept() races we currently have this cross over
	 * connection attempt second connection for one node.
	 *
	 * There is a solution to avoid the race by introducing a connect
	 * rule as e.g. our_nodeid > nodeid_to_connect who is allowed to
	 * connect. Otherside can connect but will only be considered that
	 * the other side wants to have a reconnect.
	 *
	 * However changing to this behaviour will break backwards compatible.
	 * In a DLM protocol major version upgrade we should remove this!
	 */
	struct connection *othercon;
	struct work_struct rwork; /* receive worker */
	struct work_struct swork; /* send worker */
	wait_queue_head_t shutdown_wait;
	unsigned char rx_leftover_buf[DLM_MAX_SOCKET_BUFSIZE];
	int rx_leftover;
	int mark;
	int addr_count;
	int curr_addr_index;
	struct sockaddr_storage addr[DLM_MAX_ADDR_COUNT];
	spinlock_t addrs_lock;
	struct rcu_head rcu;
};
#define sock2con(x) ((struct connection *)(x)->sk_user_data)

struct listen_connection {
	struct socket *sock;
	struct work_struct rwork;
};

#define DLM_WQ_REMAIN_BYTES(e) (PAGE_SIZE - e->end)
#define DLM_WQ_LENGTH_BYTES(e) (e->end - e->offset)

/* An entry waiting to be sent */
struct writequeue_entry {
	struct list_head list;
	struct page *page;
	int offset;
	int len;
	int end;
	int users;
	bool dirty;
	struct connection *con;
	struct list_head msgs;
	struct kref ref;
};

struct dlm_msg {
	struct writequeue_entry *entry;
	struct dlm_msg *orig_msg;
	bool retransmit;
	void *ppc;
	int len;
	int idx; /* new()/commit() idx exchange */

	struct list_head list;
	struct kref ref;
};

struct processqueue_entry {
	unsigned char *buf;
	int nodeid;
	int buflen;

	struct list_head list;
};

Annotation

Implementation Notes