summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-04-12 02:31:17 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-04-12 02:31:17 -0700
commit193ce3bea659ee78cff8288b5e9ec9186fcb1b30 (patch)
tree692380518671e92adc505c7072aaee0225af3d82 /include/linux
parentf2d816ef30bba85a850166fa3a6404a544f8849f (diff)
parent78a21ca05cd8217251d1bcb96b72f9dca11a4eaf (diff)
Merge NFS conflicts
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/nfs4.h131
-rw-r--r--include/linux/nfs_fs.h16
-rw-r--r--include/linux/nfs_fs_sb.h11
-rw-r--r--include/linux/nfs_page.h42
-rw-r--r--include/linux/nfs_xdr.h276
-rw-r--r--include/linux/sunrpc/sched.h66
-rw-r--r--include/linux/sunrpc/xdr.h91
-rw-r--r--include/linux/sunrpc/xprt.h9
8 files changed, 323 insertions, 319 deletions
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 520545881a52..89da81cca477 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -47,6 +47,11 @@
#define NFS4_ACE_SYSTEM_AUDIT_ACE_TYPE 2
#define NFS4_ACE_SYSTEM_ALARM_ACE_TYPE 3
+#define ACL4_SUPPORT_ALLOW_ACL 0x01
+#define ACL4_SUPPORT_DENY_ACL 0x02
+#define ACL4_SUPPORT_AUDIT_ACL 0x04
+#define ACL4_SUPPORT_ALARM_ACL 0x08
+
typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier;
typedef struct { char data[16]; } nfs4_stateid;
@@ -217,64 +222,64 @@ enum lock_type4 {
/* Mandatory Attributes */
-#define FATTR4_WORD0_SUPPORTED_ATTRS (1)
-#define FATTR4_WORD0_TYPE (1 << 1)
-#define FATTR4_WORD0_FH_EXPIRE_TYPE (1 << 2)
-#define FATTR4_WORD0_CHANGE (1 << 3)
-#define FATTR4_WORD0_SIZE (1 << 4)
-#define FATTR4_WORD0_LINK_SUPPORT (1 << 5)
-#define FATTR4_WORD0_SYMLINK_SUPPORT (1 << 6)
-#define FATTR4_WORD0_NAMED_ATTR (1 << 7)
-#define FATTR4_WORD0_FSID (1 << 8)
-#define FATTR4_WORD0_UNIQUE_HANDLES (1 << 9)
-#define FATTR4_WORD0_LEASE_TIME (1 << 10)
-#define FATTR4_WORD0_RDATTR_ERROR (1 << 11)
+#define FATTR4_WORD0_SUPPORTED_ATTRS (1UL << 0)
+#define FATTR4_WORD0_TYPE (1UL << 1)
+#define FATTR4_WORD0_FH_EXPIRE_TYPE (1UL << 2)
+#define FATTR4_WORD0_CHANGE (1UL << 3)
+#define FATTR4_WORD0_SIZE (1UL << 4)
+#define FATTR4_WORD0_LINK_SUPPORT (1UL << 5)
+#define FATTR4_WORD0_SYMLINK_SUPPORT (1UL << 6)
+#define FATTR4_WORD0_NAMED_ATTR (1UL << 7)
+#define FATTR4_WORD0_FSID (1UL << 8)
+#define FATTR4_WORD0_UNIQUE_HANDLES (1UL << 9)
+#define FATTR4_WORD0_LEASE_TIME (1UL << 10)
+#define FATTR4_WORD0_RDATTR_ERROR (1UL << 11)
/* Recommended Attributes */
-#define FATTR4_WORD0_ACL (1 << 12)
-#define FATTR4_WORD0_ACLSUPPORT (1 << 13)
-#define FATTR4_WORD0_ARCHIVE (1 << 14)
-#define FATTR4_WORD0_CANSETTIME (1 << 15)
-#define FATTR4_WORD0_CASE_INSENSITIVE (1 << 16)
-#define FATTR4_WORD0_CASE_PRESERVING (1 << 17)
-#define FATTR4_WORD0_CHOWN_RESTRICTED (1 << 18)
-#define FATTR4_WORD0_FILEHANDLE (1 << 19)
-#define FATTR4_WORD0_FILEID (1 << 20)
-#define FATTR4_WORD0_FILES_AVAIL (1 << 21)
-#define FATTR4_WORD0_FILES_FREE (1 << 22)
-#define FATTR4_WORD0_FILES_TOTAL (1 << 23)
-#define FATTR4_WORD0_FS_LOCATIONS (1 << 24)
-#define FATTR4_WORD0_HIDDEN (1 << 25)
-#define FATTR4_WORD0_HOMOGENEOUS (1 << 26)
-#define FATTR4_WORD0_MAXFILESIZE (1 << 27)
-#define FATTR4_WORD0_MAXLINK (1 << 28)
-#define FATTR4_WORD0_MAXNAME (1 << 29)
-#define FATTR4_WORD0_MAXREAD (1 << 30)
-#define FATTR4_WORD0_MAXWRITE (1 << 31)
-#define FATTR4_WORD1_MIMETYPE (1)
-#define FATTR4_WORD1_MODE (1 << 1)
-#define FATTR4_WORD1_NO_TRUNC (1 << 2)
-#define FATTR4_WORD1_NUMLINKS (1 << 3)
-#define FATTR4_WORD1_OWNER (1 << 4)
-#define FATTR4_WORD1_OWNER_GROUP (1 << 5)
-#define FATTR4_WORD1_QUOTA_HARD (1 << 6)
-#define FATTR4_WORD1_QUOTA_SOFT (1 << 7)
-#define FATTR4_WORD1_QUOTA_USED (1 << 8)
-#define FATTR4_WORD1_RAWDEV (1 << 9)
-#define FATTR4_WORD1_SPACE_AVAIL (1 << 10)
-#define FATTR4_WORD1_SPACE_FREE (1 << 11)
-#define FATTR4_WORD1_SPACE_TOTAL (1 << 12)
-#define FATTR4_WORD1_SPACE_USED (1 << 13)
-#define FATTR4_WORD1_SYSTEM (1 << 14)
-#define FATTR4_WORD1_TIME_ACCESS (1 << 15)
-#define FATTR4_WORD1_TIME_ACCESS_SET (1 << 16)
-#define FATTR4_WORD1_TIME_BACKUP (1 << 17)
-#define FATTR4_WORD1_TIME_CREATE (1 << 18)
-#define FATTR4_WORD1_TIME_DELTA (1 << 19)
-#define FATTR4_WORD1_TIME_METADATA (1 << 20)
-#define FATTR4_WORD1_TIME_MODIFY (1 << 21)
-#define FATTR4_WORD1_TIME_MODIFY_SET (1 << 22)
-#define FATTR4_WORD1_MOUNTED_ON_FILEID (1 << 23)
+#define FATTR4_WORD0_ACL (1UL << 12)
+#define FATTR4_WORD0_ACLSUPPORT (1UL << 13)
+#define FATTR4_WORD0_ARCHIVE (1UL << 14)
+#define FATTR4_WORD0_CANSETTIME (1UL << 15)
+#define FATTR4_WORD0_CASE_INSENSITIVE (1UL << 16)
+#define FATTR4_WORD0_CASE_PRESERVING (1UL << 17)
+#define FATTR4_WORD0_CHOWN_RESTRICTED (1UL << 18)
+#define FATTR4_WORD0_FILEHANDLE (1UL << 19)
+#define FATTR4_WORD0_FILEID (1UL << 20)
+#define FATTR4_WORD0_FILES_AVAIL (1UL << 21)
+#define FATTR4_WORD0_FILES_FREE (1UL << 22)
+#define FATTR4_WORD0_FILES_TOTAL (1UL << 23)
+#define FATTR4_WORD0_FS_LOCATIONS (1UL << 24)
+#define FATTR4_WORD0_HIDDEN (1UL << 25)
+#define FATTR4_WORD0_HOMOGENEOUS (1UL << 26)
+#define FATTR4_WORD0_MAXFILESIZE (1UL << 27)
+#define FATTR4_WORD0_MAXLINK (1UL << 28)
+#define FATTR4_WORD0_MAXNAME (1UL << 29)
+#define FATTR4_WORD0_MAXREAD (1UL << 30)
+#define FATTR4_WORD0_MAXWRITE (1UL << 31)
+#define FATTR4_WORD1_MIMETYPE (1UL << 0)
+#define FATTR4_WORD1_MODE (1UL << 1)
+#define FATTR4_WORD1_NO_TRUNC (1UL << 2)
+#define FATTR4_WORD1_NUMLINKS (1UL << 3)
+#define FATTR4_WORD1_OWNER (1UL << 4)
+#define FATTR4_WORD1_OWNER_GROUP (1UL << 5)
+#define FATTR4_WORD1_QUOTA_HARD (1UL << 6)
+#define FATTR4_WORD1_QUOTA_SOFT (1UL << 7)
+#define FATTR4_WORD1_QUOTA_USED (1UL << 8)
+#define FATTR4_WORD1_RAWDEV (1UL << 9)
+#define FATTR4_WORD1_SPACE_AVAIL (1UL << 10)
+#define FATTR4_WORD1_SPACE_FREE (1UL << 11)
+#define FATTR4_WORD1_SPACE_TOTAL (1UL << 12)
+#define FATTR4_WORD1_SPACE_USED (1UL << 13)
+#define FATTR4_WORD1_SYSTEM (1UL << 14)
+#define FATTR4_WORD1_TIME_ACCESS (1UL << 15)
+#define FATTR4_WORD1_TIME_ACCESS_SET (1UL << 16)
+#define FATTR4_WORD1_TIME_BACKUP (1UL << 17)
+#define FATTR4_WORD1_TIME_CREATE (1UL << 18)
+#define FATTR4_WORD1_TIME_DELTA (1UL << 19)
+#define FATTR4_WORD1_TIME_METADATA (1UL << 20)
+#define FATTR4_WORD1_TIME_MODIFY (1UL << 21)
+#define FATTR4_WORD1_TIME_MODIFY_SET (1UL << 22)
+#define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23)
#define NFSPROC4_NULL 0
#define NFSPROC4_COMPOUND 1
@@ -287,7 +292,6 @@ enum lock_type4 {
enum {
NFSPROC4_CLNT_NULL = 0, /* Unused */
- NFSPROC4_CLNT_COMPOUND, /* Soon to be unused */
NFSPROC4_CLNT_READ,
NFSPROC4_CLNT_WRITE,
NFSPROC4_CLNT_COMMIT,
@@ -304,6 +308,19 @@ enum {
NFSPROC4_CLNT_LOCK,
NFSPROC4_CLNT_LOCKT,
NFSPROC4_CLNT_LOCKU,
+ NFSPROC4_CLNT_ACCESS,
+ NFSPROC4_CLNT_GETATTR,
+ NFSPROC4_CLNT_LOOKUP,
+ NFSPROC4_CLNT_LOOKUP_ROOT,
+ NFSPROC4_CLNT_REMOVE,
+ NFSPROC4_CLNT_RENAME,
+ NFSPROC4_CLNT_LINK,
+ NFSPROC4_CLNT_CREATE,
+ NFSPROC4_CLNT_PATHCONF,
+ NFSPROC4_CLNT_STATFS,
+ NFSPROC4_CLNT_READLINK,
+ NFSPROC4_CLNT_READDIR,
+ NFSPROC4_CLNT_SERVER_CAPS,
};
#endif
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 47123702fbd5..fccbab4d02b5 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -69,6 +69,8 @@
#define FLUSH_SYNC 1 /* file being synced, or contention */
#define FLUSH_WAIT 2 /* wait for completion */
#define FLUSH_STABLE 4 /* commit to stable storage */
+#define FLUSH_LOWPRI 8 /* low priority background flush */
+#define FLUSH_HIGHPRI 16 /* high priority memory reclaim flush */
#ifdef __KERNEL__
@@ -275,6 +277,7 @@ extern void nfs_begin_attr_update(struct inode *);
extern void nfs_end_attr_update(struct inode *);
extern void nfs_begin_data_update(struct inode *);
extern void nfs_end_data_update(struct inode *);
+extern void nfs_end_data_update_defer(struct inode *);
/* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
extern u32 root_nfs_parse_addr(char *name); /*__init*/
@@ -335,10 +338,8 @@ extern int nfs_writepages(struct address_space *, struct writeback_control *);
extern int nfs_flush_incompatible(struct file *file, struct page *page);
extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int);
extern void nfs_writeback_done(struct rpc_task *task);
-extern void nfs_writedata_release(struct rpc_task *task);
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
-extern void nfs_commit_release(struct rpc_task *task);
extern void nfs_commit_done(struct rpc_task *);
#endif
@@ -376,14 +377,18 @@ nfs_wb_all(struct inode *inode)
/*
* Write back all requests on one page - we do this before reading it.
*/
-static inline int
-nfs_wb_page(struct inode *inode, struct page* page)
+static inline int nfs_wb_page_priority(struct inode *inode, struct page* page, int how)
{
int error = nfs_sync_inode(inode, page->index, 1,
- FLUSH_WAIT | FLUSH_STABLE);
+ how | FLUSH_WAIT | FLUSH_STABLE);
return (error < 0) ? error : 0;
}
+static inline int nfs_wb_page(struct inode *inode, struct page* page)
+{
+ return nfs_wb_page_priority(inode, page, 0);
+}
+
/* Hack for future NFS swap support */
#ifndef IS_SWAPFILE
# define IS_SWAPFILE(inode) (0)
@@ -397,7 +402,6 @@ extern int nfs_readpages(struct file *, struct address_space *,
struct list_head *, unsigned);
extern int nfs_pagein_list(struct list_head *, int);
extern void nfs_readpage_result(struct rpc_task *);
-extern void nfs_readdata_release(struct rpc_task *);
/*
* linux/fs/mount_clnt.c
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 1b5f7e130502..428355f8aaf9 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -38,10 +38,19 @@ struct nfs_server {
struct list_head nfs4_siblings; /* List of other nfs_server structs
* that share the same clientid
*/
+ u32 attr_bitmask[2];/* V4 bitmask representing the set
+ of attributes supported on this
+ filesystem */
+ u32 acl_bitmask; /* V4 bitmask representing the ACEs
+ that are supported on this
+ filesystem */
#endif
};
/* Server capabilities */
-#define NFS_CAP_READDIRPLUS (1)
+#define NFS_CAP_READDIRPLUS (1U << 0)
+#define NFS_CAP_HARDLINKS (1U << 1)
+#define NFS_CAP_SYMLINKS (1U << 2)
+#define NFS_CAP_ACLS (1U << 3)
#endif
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index c648312afc0c..454587123f33 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -17,10 +17,14 @@
#include <linux/sunrpc/auth.h>
#include <linux/nfs_xdr.h>
+#include <asm/atomic.h>
+
/*
* Valid flags for a dirty buffer
*/
#define PG_BUSY 0
+#define PG_NEED_COMMIT 1
+#define PG_NEED_RESCHED 2
struct nfs_page {
struct list_head wb_list, /* Defines state of page: */
@@ -31,6 +35,7 @@ struct nfs_page {
struct rpc_cred *wb_cred;
struct nfs4_state *wb_state;
struct page *wb_page; /* page to read in/write out */
+ atomic_t wb_complete; /* i/os we're waiting for */
wait_queue_head_t wb_wait; /* wait queue */
unsigned long wb_index; /* Offset >> PAGE_CACHE_SHIFT */
unsigned int wb_offset, /* Offset & ~PAGE_CACHE_MASK */
@@ -42,6 +47,8 @@ struct nfs_page {
};
#define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags))
+#define NFS_NEED_COMMIT(req) (test_bit(PG_NEED_COMMIT,&(req)->wb_flags))
+#define NFS_NEED_RESCHED(req) (test_bit(PG_NEED_RESCHED,&(req)->wb_flags))
extern struct nfs_page *nfs_create_request(struct file *, struct inode *,
struct page *,
@@ -93,8 +100,7 @@ nfs_unlock_request(struct nfs_page *req)
smp_mb__before_clear_bit();
clear_bit(PG_BUSY, &req->wb_flags);
smp_mb__after_clear_bit();
- if (waitqueue_active(&req->wb_wait))
- wake_up_all(&req->wb_wait);
+ wake_up_all(&req->wb_wait);
nfs_release_request(req);
}
@@ -115,6 +121,38 @@ nfs_list_remove_request(struct nfs_page *req)
req->wb_list_head = NULL;
}
+static inline int
+nfs_defer_commit(struct nfs_page *req)
+{
+ if (test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags))
+ return 0;
+ return 1;
+}
+
+static inline void
+nfs_clear_commit(struct nfs_page *req)
+{
+ smp_mb__before_clear_bit();
+ clear_bit(PG_NEED_COMMIT, &req->wb_flags);
+ smp_mb__after_clear_bit();
+}
+
+static inline int
+nfs_defer_reschedule(struct nfs_page *req)
+{
+ if (test_and_set_bit(PG_NEED_RESCHED, &req->wb_flags))
+ return 0;
+ return 1;
+}
+
+static inline void
+nfs_clear_reschedule(struct nfs_page *req)
+{
+ smp_mb__before_clear_bit();
+ clear_bit(PG_NEED_RESCHED, &req->wb_flags);
+ smp_mb__after_clear_bit();
+}
+
static inline struct nfs_page *
nfs_list_entry(struct list_head *head)
{
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 52d87f29fdc4..f47e3c27af27 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -3,6 +3,11 @@
#include <linux/sunrpc/xprt.h>
+struct nfs4_fsid {
+ __u64 major;
+ __u64 minor;
+};
+
struct nfs_fattr {
unsigned short valid; /* which fields are valid */
__u64 pre_size; /* pre_op_attr.size */
@@ -26,10 +31,7 @@ struct nfs_fattr {
dev_t rdev;
union {
__u64 nfs3; /* also nfs2 */
- struct {
- __u64 major;
- __u64 minor;
- } nfs4;
+ struct nfs4_fsid nfs4;
} fsid_u;
__u64 fileid;
struct timespec atime;
@@ -87,6 +89,12 @@ struct nfs_pathconf {
__u32 max_namelen; /* max name length */
};
+struct nfs4_change_info {
+ u32 atomic;
+ u64 before;
+ u64 after;
+};
+
/*
* Arguments to the open call.
*/
@@ -102,20 +110,18 @@ struct nfs_openargs {
struct iattr * attrs; /* UNCHECKED, GUARDED */
nfs4_verifier verifier; /* EXCLUSIVE */
} u;
- struct qstr * name;
- struct nfs4_getattr * f_getattr;
- struct nfs4_getattr * d_getattr;
- struct nfs_server * server; /* Needed for ID mapping */
+ const struct qstr * name;
+ const struct nfs_server *server; /* Needed for ID mapping */
+ const u32 * bitmask;
};
struct nfs_openres {
nfs4_stateid stateid;
struct nfs_fh fh;
- struct nfs4_change_info * cinfo;
+ struct nfs4_change_info cinfo;
__u32 rflags;
- struct nfs4_getattr * f_getattr;
- struct nfs4_getattr * d_getattr;
- struct nfs_server * server;
+ struct nfs_fattr * f_attr;
+ const struct nfs_server *server;
};
/*
@@ -141,7 +147,7 @@ struct nfs_open_reclaimargs {
__u32 id;
__u32 share_access;
__u32 claim;
- struct nfs4_getattr * f_getattr;
+ const __u32 * bitmask;
};
/*
@@ -215,7 +221,7 @@ struct nfs_lockres {
nfs4_stateid stateid;/* LOCK success, LOCKU */
struct nfs_lock_denied denied; /* LOCK failed, LOCKT success */
} u;
- struct nfs_server * server;
+ const struct nfs_server * server;
};
/*
@@ -229,7 +235,8 @@ struct nfs_lockres {
struct nfs_readargs {
struct nfs_fh * fh;
- nfs4_stateid stateid;
+ fl_owner_t lockowner;
+ struct nfs4_state * state;
__u64 offset;
__u32 count;
unsigned int pgbase;
@@ -252,7 +259,8 @@ struct nfs_readres {
struct nfs_writeargs {
struct nfs_fh * fh;
- nfs4_stateid stateid;
+ fl_owner_t lockowner;
+ struct nfs4_state * state;
__u64 offset;
__u32 count;
enum nfs3_stable_how stable;
@@ -319,13 +327,13 @@ struct nfs_setattrargs {
struct nfs_fh * fh;
nfs4_stateid stateid;
struct iattr * iap;
- struct nfs4_getattr * attr;
- struct nfs_server * server; /* Needed for name mapping */
+ const struct nfs_server * server; /* Needed for name mapping */
+ const u32 * bitmask;
};
struct nfs_setattrres {
- struct nfs4_getattr * attr;
- struct nfs_server * server;
+ struct nfs_fattr * fattr;
+ const struct nfs_server * server;
};
struct nfs_linkargs {
@@ -476,124 +484,116 @@ struct nfs3_readdirres {
typedef u64 clientid4;
-struct nfs4_change_info {
- u32 atomic;
- u64 before;
- u64 after;
+struct nfs4_accessargs {
+ const struct nfs_fh * fh;
+ u32 access;
};
-struct nfs4_access {
- u32 ac_req_access; /* request */
- u32 * ac_resp_supported; /* response */
- u32 * ac_resp_access; /* response */
+struct nfs4_accessres {
+ u32 supported;
+ u32 access;
};
-struct nfs4_close {
- char * cl_stateid; /* request */
- u32 cl_seqid; /* request */
-};
-
-struct nfs4_create {
- u32 cr_ftype; /* request */
- union { /* request */
- struct {
- u32 textlen;
- const char * text;
- } symlink; /* NF4LNK */
+struct nfs4_create_arg {
+ u32 ftype;
+ union {
+ struct qstr * symlink; /* NF4LNK */
struct {
u32 specdata1;
u32 specdata2;
} device; /* NF4BLK, NF4CHR */
} u;
- u32 cr_namelen; /* request */
- const char * cr_name; /* request */
- struct iattr * cr_attrs; /* request */
- struct nfs4_change_info * cr_cinfo; /* response */
+ const struct qstr * name;
+ const struct nfs_server * server;
+ const struct iattr * attrs;
+ const struct nfs_fh * dir_fh;
+ const u32 * bitmask;
};
-#define cr_textlen u.symlink.textlen
-#define cr_text u.symlink.text
-#define cr_specdata1 u.device.specdata1
-#define cr_specdata2 u.device.specdata2
-struct nfs4_getattr {
- u32 * gt_bmval; /* request */
- struct nfs_fattr * gt_attrs; /* response */
- struct nfs_fsstat * gt_fsstat; /* response */
- struct nfs_pathconf * gt_pathconf; /* response */
+struct nfs4_create_res {
+ const struct nfs_server * server;
+ struct nfs_fh * fh;
+ struct nfs_fattr * fattr;
+ struct nfs4_change_info dir_cinfo;
};
-struct nfs4_getfh {
- struct nfs_fh * gf_fhandle; /* response */
+struct nfs4_fsinfo_arg {
+ const struct nfs_fh * fh;
+ const u32 * bitmask;
};
-struct nfs4_link {
- u32 ln_namelen; /* request */
- const char * ln_name; /* request */
- struct nfs4_change_info * ln_cinfo; /* response */
+struct nfs4_getattr_arg {
+ const struct nfs_fh * fh;
+ const u32 * bitmask;
};
-struct nfs4_lookup {
- struct qstr * lo_name; /* request */
+struct nfs4_getattr_res {
+ const struct nfs_server * server;
+ struct nfs_fattr * fattr;
};
-struct nfs4_open {
- struct nfs4_client * op_client_state; /* request */
- u32 op_share_access; /* request */
- u32 op_opentype; /* request */
- u32 op_createmode; /* request */
- union { /* request */
- struct iattr * attrs; /* UNCHECKED, GUARDED */
- nfs4_verifier verifier; /* EXCLUSIVE */
- } u;
- struct qstr * op_name; /* request */
- char * op_stateid; /* response */
- struct nfs4_change_info * op_cinfo; /* response */
- u32 * op_rflags; /* response */
+struct nfs4_link_arg {
+ const struct nfs_fh * fh;
+ const struct nfs_fh * dir_fh;
+ const struct qstr * name;
+};
+
+struct nfs4_lookup_arg {
+ const struct nfs_fh * dir_fh;
+ const struct qstr * name;
+ const u32 * bitmask;
};
-#define op_attrs u.attrs
-#define op_verifier u.verifier
-struct nfs4_open_confirm {
- char * oc_stateid; /* request */
+struct nfs4_lookup_res {
+ const struct nfs_server * server;
+ struct nfs_fattr * fattr;
+ struct nfs_fh * fh;
};
-struct nfs4_putfh {
- struct nfs_fh * pf_fhandle; /* request */
+struct nfs4_lookup_root_arg {
+ const u32 * bitmask;
};
-struct nfs4_readdir {
- u64 rd_cookie; /* request */
- nfs4_verifier rd_req_verifier; /* request */
- u32 rd_count; /* request */
- u32 rd_bmval[2]; /* request */
- nfs4_verifier rd_resp_verifier; /* response */
- struct page ** rd_pages; /* zero-copy data */
- unsigned int rd_pgbase; /* zero-copy data */
+struct nfs4_pathconf_arg {
+ const struct nfs_fh * fh;
+ const u32 * bitmask;
+};
+
+struct nfs4_readdir_arg {
+ const struct nfs_fh * fh;
+ u64 cookie;
+ nfs4_verifier verifier;
+ u32 count;
+ struct page ** pages; /* zero-copy data */
+ unsigned int pgbase; /* zero-copy data */
+};
+
+struct nfs4_readdir_res {
+ nfs4_verifier verifier;
+ unsigned int pgbase;
};
struct nfs4_readlink {
- u32 rl_count; /* zero-copy data */
- struct page ** rl_pages; /* zero-copy data */
+ const struct nfs_fh * fh;
+ u32 count; /* zero-copy data */
+ struct page ** pages; /* zero-copy data */
};
-struct nfs4_remove {
- u32 rm_namelen; /* request */
- const char * rm_name; /* request */
- struct nfs4_change_info * rm_cinfo; /* response */
+struct nfs4_remove_arg {
+ const struct nfs_fh * fh;
+ const struct qstr * name;
};
-struct nfs4_rename {
- u32 rn_oldnamelen; /* request */
- const char * rn_oldname; /* request */
- u32 rn_newnamelen; /* request */
- const char * rn_newname; /* request */
- struct nfs4_change_info * rn_src_cinfo; /* response */
- struct nfs4_change_info * rn_dst_cinfo; /* response */
+struct nfs4_rename_arg {
+ const struct nfs_fh * old_dir;
+ const struct nfs_fh * new_dir;
+ const struct qstr * old_name;
+ const struct qstr * new_name;
};
-struct nfs4_setattr {
- char * st_stateid; /* request */
- struct iattr * st_iap; /* request */
+struct nfs4_rename_res {
+ struct nfs4_change_info old_cinfo;
+ struct nfs4_change_info new_cinfo;
};
struct nfs4_setclientid {
@@ -606,70 +606,37 @@ struct nfs4_setclientid {
struct nfs4_client * sc_state; /* response */
};
-struct nfs4_op {
- u32 opnum;
- union {
- struct nfs4_access access;
- struct nfs4_close close;
- struct nfs4_create create;
- struct nfs4_getattr getattr;
- struct nfs4_getfh getfh;
- struct nfs4_link link;
- struct nfs4_lookup lookup;
- struct nfs4_open open;
- struct nfs4_open_confirm open_confirm;
- struct nfs4_putfh putfh;
- struct nfs4_readdir readdir;
- struct nfs4_readlink readlink;
- struct nfs4_remove remove;
- struct nfs4_rename rename;
- struct nfs4_client * renew;
- struct nfs4_setattr setattr;
- } u;
+struct nfs4_statfs_arg {
+ const struct nfs_fh * fh;
+ const u32 * bitmask;
};
-struct nfs4_compound {
- unsigned int flags; /* defined below */
- struct nfs_server * server;
-
- /* RENEW information */
- int renew_index;
- unsigned long timestamp;
-
- /* scratch variables for XDR encode/decode */
- int nops;
- u32 * p;
- u32 * end;
-
- /* the individual COMPOUND operations */
- struct nfs4_op *ops;
-
- /* request */
- int req_nops;
- u32 taglen;
- char * tag;
-
- /* response */
- int resp_nops;
- int toplevel_status;
+struct nfs4_server_caps_res {
+ u32 attr_bitmask[2];
+ u32 acl_bitmask;
+ u32 has_links;
+ u32 has_symlinks;
};
#endif /* CONFIG_NFS_V4 */
+struct nfs_page;
+
struct nfs_read_data {
int flags;
struct rpc_task task;
struct inode *inode;
struct rpc_cred *cred;
- fl_owner_t lockowner;
struct nfs_fattr fattr; /* fattr storage */
struct list_head pages; /* Coalesced read requests */
+ struct nfs_page *req; /* multi ops per nfs_page */
struct page *pagevec[NFS_READ_MAXIOV];
struct nfs_readargs args;
struct nfs_readres res;
#ifdef CONFIG_NFS_V4
unsigned long timestamp; /* For lease renewal */
#endif
+ void (*complete) (struct nfs_read_data *, int);
};
struct nfs_write_data {
@@ -677,20 +644,19 @@ struct nfs_write_data {
struct rpc_task task;
struct inode *inode;
struct rpc_cred *cred;
- fl_owner_t lockowner;
struct nfs_fattr fattr;
struct nfs_writeverf verf;
struct list_head pages; /* Coalesced requests we wish to flush */
+ struct nfs_page *req; /* multi ops per nfs_page */
struct page *pagevec[NFS_WRITE_MAXIOV];
struct nfs_writeargs args; /* argument struct */
struct nfs_writeres res; /* result struct */
#ifdef CONFIG_NFS_V4
unsigned long timestamp; /* For lease renewal */
#endif
+ void (*complete) (struct nfs_write_data *, int);
};
-struct nfs_page;
-
/*
* RPC procedure vector for NFSv2/NFSv3 demuxing
*/
@@ -737,9 +703,9 @@ struct nfs_rpc_ops {
int (*pathconf) (struct nfs_server *, struct nfs_fh *,
struct nfs_pathconf *);
u32 * (*decode_dirent)(u32 *, struct nfs_entry *, int plus);
- void (*read_setup) (struct nfs_read_data *, unsigned int count);
- void (*write_setup) (struct nfs_write_data *, unsigned int count, int how);
- void (*commit_setup) (struct nfs_write_data *, u64 start, u32 len, int how);
+ void (*read_setup) (struct nfs_read_data *);
+ void (*write_setup) (struct nfs_write_data *, int how);
+ void (*commit_setup) (struct nfs_write_data *, int how);
int (*file_open) (struct inode *, struct file *);
int (*file_release) (struct inode *, struct file *);
void (*request_init)(struct nfs_page *, struct file *);
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index 6b8e3eb91513..be2e6ef3b793 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -49,6 +49,8 @@ struct rpc_task {
tk_cred_retry,
tk_suid_retry;
+ unsigned long tk_cookie; /* Cookie for batching tasks */
+
/*
* timeout_fn to be executed by timer bottom half
* callback to be executed after waking up
@@ -72,7 +74,9 @@ struct rpc_task {
unsigned long tk_timeout; /* timeout for rpc_sleep() */
unsigned short tk_flags; /* misc flags */
unsigned char tk_active : 1;/* Task has been activated */
+ unsigned char tk_priority : 2;/* Task priority */
unsigned long tk_runstate; /* Task run status */
+ struct list_head tk_links; /* links to related tasks */
#ifdef RPC_DEBUG
unsigned short tk_pid; /* debugging aid */
#endif
@@ -138,28 +142,58 @@ typedef void (*rpc_action)(struct rpc_task *);
} while(0)
/*
+ * Task priorities.
+ * Note: if you change these, you must also change
+ * the task initialization definitions below.
+ */
+#define RPC_PRIORITY_LOW 0
+#define RPC_PRIORITY_NORMAL 1
+#define RPC_PRIORITY_HIGH 2
+#define RPC_NR_PRIORITY (RPC_PRIORITY_HIGH+1)
+
+/*
* RPC synchronization objects
*/
struct rpc_wait_queue {
- struct list_head tasks;
+ struct list_head tasks[RPC_NR_PRIORITY]; /* task queue for each priority level */
+ unsigned long cookie; /* cookie of last task serviced */
+ unsigned char maxpriority; /* maximum priority (0 if queue is not a priority queue) */
+ unsigned char priority; /* current priority */
+ unsigned char count; /* # task groups remaining serviced so far */
+ unsigned char nr; /* # tasks remaining for cookie */
#ifdef RPC_DEBUG
- char * name;
+ const char * name;
#endif
};
+/*
+ * This is the # requests to send consecutively
+ * from a single cookie. The aim is to improve
+ * performance of NFS operations such as read/write.
+ */
+#define RPC_BATCH_COUNT 16
+
#ifndef RPC_DEBUG
-# define RPC_WAITQ_INIT(var,qname) ((struct rpc_wait_queue) {LIST_HEAD_INIT(var)})
-# define RPC_WAITQ(var,qname) struct rpc_wait_queue var = RPC_WAITQ_INIT(var.tasks,qname)
-# define INIT_RPC_WAITQ(ptr,qname) do { \
- INIT_LIST_HEAD(&(ptr)->tasks); \
- } while(0)
+# define RPC_WAITQ_INIT(var,qname) { \
+ .tasks = { \
+ [0] = LIST_HEAD_INIT(var.tasks[0]), \
+ [1] = LIST_HEAD_INIT(var.tasks[1]), \
+ [2] = LIST_HEAD_INIT(var.tasks[2]), \
+ }, \
+ }
#else
-# define RPC_WAITQ_INIT(var,qname) ((struct rpc_wait_queue) {LIST_HEAD_INIT(var.tasks), qname})
-# define RPC_WAITQ(var,qname) struct rpc_wait_queue var = RPC_WAITQ_INIT(var,qname)
-# define INIT_RPC_WAITQ(ptr,qname) do { \
- INIT_LIST_HEAD(&(ptr)->tasks); (ptr)->name = qname; \
- } while(0)
+# define RPC_WAITQ_INIT(var,qname) { \
+ .tasks = { \
+ [0] = LIST_HEAD_INIT(var.tasks[0]), \
+ [1] = LIST_HEAD_INIT(var.tasks[1]), \
+ [2] = LIST_HEAD_INIT(var.tasks[2]), \
+ }, \
+ .name = qname, \
+ }
#endif
+# define RPC_WAITQ(var,qname) struct rpc_wait_queue var = RPC_WAITQ_INIT(var,qname)
+
+#define RPC_IS_PRIORITY(q) ((q)->maxpriority > 0)
/*
* Function prototypes
@@ -175,6 +209,8 @@ void rpc_run_child(struct rpc_task *parent, struct rpc_task *child,
rpc_action action);
int rpc_add_wait_queue(struct rpc_wait_queue *, struct rpc_task *);
void rpc_remove_wait_queue(struct rpc_task *);
+void rpc_init_priority_wait_queue(struct rpc_wait_queue *, const char *);
+void rpc_init_wait_queue(struct rpc_wait_queue *, const char *);
void rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *,
rpc_action action, rpc_action timer);
void rpc_add_timer(struct rpc_task *, rpc_action);
@@ -194,16 +230,14 @@ void rpc_show_tasks(void);
int rpc_init_mempool(void);
void rpc_destroy_mempool(void);
-static __inline__ void
-rpc_exit(struct rpc_task *task, int status)
+static inline void rpc_exit(struct rpc_task *task, int status)
{
task->tk_status = status;
task->tk_action = NULL;
}
#ifdef RPC_DEBUG
-static __inline__ char *
-rpc_qname(struct rpc_wait_queue *q)
+static inline const char * rpc_qname(struct rpc_wait_queue *q)
{
return ((q && q->name) ? q->name : "unknown");
}
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 2b334dc19962..0b9aecd9b8c3 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -55,7 +55,8 @@ struct xdr_buf {
unsigned int page_base, /* Start of page data */
page_len; /* Length of page data */
- unsigned int len; /* Total length of data */
+ unsigned int buflen, /* Total length of storage buffer */
+ len; /* Length of XDR encoded message */
};
@@ -87,7 +88,8 @@ struct xdr_buf {
/*
* Miscellaneous XDR helper functions
*/
-u32 * xdr_encode_array(u32 *p, const void *s, unsigned int len);
+u32 * xdr_encode_opaque_fixed(u32 *p, const void *ptr, unsigned int len);
+u32 * xdr_encode_opaque(u32 *p, const void *ptr, unsigned int len);
u32 * xdr_encode_string(u32 *p, const char *s);
u32 * xdr_decode_string(u32 *p, char **sp, int *lenp, int maxlen);
u32 * xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen);
@@ -100,6 +102,11 @@ void xdr_encode_pages(struct xdr_buf *, struct page **, unsigned int,
void xdr_inline_pages(struct xdr_buf *, unsigned int,
struct page **, unsigned int, unsigned int);
+static inline u32 *xdr_encode_array(u32 *p, const void *s, unsigned int len)
+{
+ return xdr_encode_opaque(p, s, len);
+}
+
/*
* Decode 64bit quantities (NFSv3 support)
*/
@@ -178,86 +185,14 @@ struct xdr_stream {
struct iovec *iov; /* pointer to the current iovec */
};
-/*
- * Initialize an xdr_stream for encoding data.
- *
- * Note: at the moment the RPC client only passes the length of our
- * scratch buffer in the xdr_buf's header iovec. Previously this
- * meant we needed to call xdr_adjust_iovec() after encoding the
- * data. With the new scheme, the xdr_stream manages the details
- * of the buffer length, and takes care of adjusting the iovec
- * length for us.
- */
-static inline void
-xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
-{
- struct iovec *iov = buf->head;
-
- xdr->buf = buf;
- xdr->iov = iov;
- xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
- buf->len = iov->iov_len = (char *)p - (char *)iov->iov_base;
- xdr->p = p;
-}
-
-/*
- * Check that we have enough buffer space to encode 'nbytes' more
- * bytes of data. If so, update the total xdr_buf length, and
- * adjust the length of the current iovec.
- */
-static inline uint32_t *
-xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes)
-{
- uint32_t *p = xdr->p;
- uint32_t *q;
-
- /* align nbytes on the next 32-bit boundary */
- nbytes += 3;
- nbytes &= ~3;
- q = p + (nbytes >> 2);
- if (unlikely(q > xdr->end || q < p))
- return NULL;
- xdr->p = q;
- xdr->iov->iov_len += nbytes;
- xdr->buf->len += nbytes;
- return p;
-}
-
+extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
+extern uint32_t *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
unsigned int base, unsigned int len);
+extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
+extern uint32_t *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
-/*
- * Initialize an xdr_stream for decoding data.
- */
-static inline void
-xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
-{
- struct iovec *iov = buf->head;
- xdr->buf = buf;
- xdr->iov = iov;
- xdr->p = p;
- xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
-}
-
-/*
- * Check if the input buffer is long enough to enable us to decode
- * 'nbytes' more bytes of data starting at the current position.
- * If so return the current pointer, then update the current
- * position.
- */
-static inline uint32_t *
-xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
-{
- uint32_t *p = xdr->p;
- uint32_t *q = p + XDR_QUADLEN(nbytes);
-
- if (unlikely(q > xdr->end || q < p))
- return NULL;
- xdr->p = q;
- return p;
-}
-
#endif /* __KERNEL__ */
#endif /* _SUNRPC_XDR_H_ */
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index e6d79afcb50c..5222a8f4c580 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -120,8 +120,6 @@ struct rpc_rqst {
};
#define rq_svec rq_snd_buf.head
#define rq_slen rq_snd_buf.len
-#define rq_rvec rq_rcv_buf.head
-#define rq_rlen rq_rcv_buf.len
#define XPRT_LAST_FRAG (1 << 0)
#define XPRT_COPY_RECM (1 << 1)
@@ -218,12 +216,15 @@ void xprt_connect(struct rpc_task *);
int xprt_clear_backlog(struct rpc_xprt *);
void xprt_sock_setbufsize(struct rpc_xprt *);
-#define XPRT_CONNECT 0
-#define XPRT_LOCKED 1
+#define XPRT_LOCKED 0
+#define XPRT_CONNECT 1
+#define XPRT_CONNECTING 2
#define xprt_connected(xp) (test_bit(XPRT_CONNECT, &(xp)->sockstate))
#define xprt_set_connected(xp) (set_bit(XPRT_CONNECT, &(xp)->sockstate))
#define xprt_test_and_set_connected(xp) (test_and_set_bit(XPRT_CONNECT, &(xp)->sockstate))
+#define xprt_test_and_clear_connected(xp) \
+ (test_and_clear_bit(XPRT_CONNECT, &(xp)->sockstate))
#define xprt_clear_connected(xp) (clear_bit(XPRT_CONNECT, &(xp)->sockstate))
#endif /* __KERNEL__*/