diff options
Diffstat (limited to 'fs/nfs/pnfs.h')
| -rw-r--r-- | fs/nfs/pnfs.h | 118 |
1 files changed, 70 insertions, 48 deletions
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index e2612ea0cbed..6380b9405bcd 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h | |||
| @@ -30,6 +30,8 @@ | |||
| 30 | #ifndef FS_NFS_PNFS_H | 30 | #ifndef FS_NFS_PNFS_H |
| 31 | #define FS_NFS_PNFS_H | 31 | #define FS_NFS_PNFS_H |
| 32 | 32 | ||
| 33 | #include <linux/nfs_page.h> | ||
| 34 | |||
| 33 | enum { | 35 | enum { |
| 34 | NFS_LSEG_VALID = 0, /* cleared when lseg is recalled/returned */ | 36 | NFS_LSEG_VALID = 0, /* cleared when lseg is recalled/returned */ |
| 35 | NFS_LSEG_ROC, /* roc bit received from server */ | 37 | NFS_LSEG_ROC, /* roc bit received from server */ |
| @@ -43,6 +45,11 @@ struct pnfs_layout_segment { | |||
| 43 | struct pnfs_layout_hdr *pls_layout; | 45 | struct pnfs_layout_hdr *pls_layout; |
| 44 | }; | 46 | }; |
| 45 | 47 | ||
| 48 | enum pnfs_try_status { | ||
| 49 | PNFS_ATTEMPTED = 0, | ||
| 50 | PNFS_NOT_ATTEMPTED = 1, | ||
| 51 | }; | ||
| 52 | |||
| 46 | #ifdef CONFIG_NFS_V4_1 | 53 | #ifdef CONFIG_NFS_V4_1 |
| 47 | 54 | ||
| 48 | #define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4" | 55 | #define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4" |
| @@ -61,10 +68,18 @@ struct pnfs_layoutdriver_type { | |||
| 61 | const u32 id; | 68 | const u32 id; |
| 62 | const char *name; | 69 | const char *name; |
| 63 | struct module *owner; | 70 | struct module *owner; |
| 64 | int (*set_layoutdriver) (struct nfs_server *); | ||
| 65 | int (*clear_layoutdriver) (struct nfs_server *); | ||
| 66 | struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr); | 71 | struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr); |
| 67 | void (*free_lseg) (struct pnfs_layout_segment *lseg); | 72 | void (*free_lseg) (struct pnfs_layout_segment *lseg); |
| 73 | |||
| 74 | /* test for nfs page cache coalescing */ | ||
| 75 | int (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); | ||
| 76 | |||
| 77 | /* | ||
| 78 | * Return PNFS_ATTEMPTED to indicate the layout code has attempted | ||
| 79 | * I/O, else return PNFS_NOT_ATTEMPTED to fall back to normal NFS | ||
| 80 | */ | ||
| 81 | enum pnfs_try_status (*read_pagelist) (struct nfs_read_data *nfs_data); | ||
| 82 | enum pnfs_try_status (*write_pagelist) (struct nfs_write_data *nfs_data, int how); | ||
| 68 | }; | 83 | }; |
| 69 | 84 | ||
| 70 | struct pnfs_layout_hdr { | 85 | struct pnfs_layout_hdr { |
| @@ -90,52 +105,6 @@ struct pnfs_device { | |||
| 90 | unsigned int pglen; | 105 | unsigned int pglen; |
| 91 | }; | 106 | }; |
| 92 | 107 | ||
| 93 | /* | ||
| 94 | * Device ID RCU cache. A device ID is unique per client ID and layout type. | ||
| 95 | */ | ||
| 96 | #define NFS4_DEVICE_ID_HASH_BITS 5 | ||
| 97 | #define NFS4_DEVICE_ID_HASH_SIZE (1 << NFS4_DEVICE_ID_HASH_BITS) | ||
| 98 | #define NFS4_DEVICE_ID_HASH_MASK (NFS4_DEVICE_ID_HASH_SIZE - 1) | ||
| 99 | |||
| 100 | static inline u32 | ||
| 101 | nfs4_deviceid_hash(struct nfs4_deviceid *id) | ||
| 102 | { | ||
| 103 | unsigned char *cptr = (unsigned char *)id->data; | ||
| 104 | unsigned int nbytes = NFS4_DEVICEID4_SIZE; | ||
| 105 | u32 x = 0; | ||
| 106 | |||
| 107 | while (nbytes--) { | ||
| 108 | x *= 37; | ||
| 109 | x += *cptr++; | ||
| 110 | } | ||
| 111 | return x & NFS4_DEVICE_ID_HASH_MASK; | ||
| 112 | } | ||
| 113 | |||
| 114 | struct pnfs_deviceid_node { | ||
| 115 | struct hlist_node de_node; | ||
| 116 | struct nfs4_deviceid de_id; | ||
| 117 | atomic_t de_ref; | ||
| 118 | }; | ||
| 119 | |||
| 120 | struct pnfs_deviceid_cache { | ||
| 121 | spinlock_t dc_lock; | ||
| 122 | atomic_t dc_ref; | ||
| 123 | void (*dc_free_callback)(struct pnfs_deviceid_node *); | ||
| 124 | struct hlist_head dc_deviceids[NFS4_DEVICE_ID_HASH_SIZE]; | ||
| 125 | }; | ||
| 126 | |||
| 127 | extern int pnfs_alloc_init_deviceid_cache(struct nfs_client *, | ||
| 128 | void (*free_callback)(struct pnfs_deviceid_node *)); | ||
| 129 | extern void pnfs_put_deviceid_cache(struct nfs_client *); | ||
| 130 | extern struct pnfs_deviceid_node *pnfs_find_get_deviceid( | ||
| 131 | struct pnfs_deviceid_cache *, | ||
| 132 | struct nfs4_deviceid *); | ||
| 133 | extern struct pnfs_deviceid_node *pnfs_add_deviceid( | ||
| 134 | struct pnfs_deviceid_cache *, | ||
| 135 | struct pnfs_deviceid_node *); | ||
| 136 | extern void pnfs_put_deviceid(struct pnfs_deviceid_cache *c, | ||
| 137 | struct pnfs_deviceid_node *devid); | ||
| 138 | |||
| 139 | extern int pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *); | 108 | extern int pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *); |
| 140 | extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *); | 109 | extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *); |
| 141 | 110 | ||
| @@ -146,11 +115,18 @@ extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp); | |||
| 146 | 115 | ||
| 147 | /* pnfs.c */ | 116 | /* pnfs.c */ |
| 148 | void get_layout_hdr(struct pnfs_layout_hdr *lo); | 117 | void get_layout_hdr(struct pnfs_layout_hdr *lo); |
| 118 | void put_lseg(struct pnfs_layout_segment *lseg); | ||
| 149 | struct pnfs_layout_segment * | 119 | struct pnfs_layout_segment * |
| 150 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, | 120 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, |
| 151 | enum pnfs_iomode access_type); | 121 | enum pnfs_iomode access_type); |
| 152 | void set_pnfs_layoutdriver(struct nfs_server *, u32 id); | 122 | void set_pnfs_layoutdriver(struct nfs_server *, u32 id); |
| 153 | void unset_pnfs_layoutdriver(struct nfs_server *); | 123 | void unset_pnfs_layoutdriver(struct nfs_server *); |
| 124 | enum pnfs_try_status pnfs_try_to_write_data(struct nfs_write_data *, | ||
| 125 | const struct rpc_call_ops *, int); | ||
| 126 | enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *, | ||
| 127 | const struct rpc_call_ops *); | ||
| 128 | void pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *); | ||
| 129 | void pnfs_pageio_init_write(struct nfs_pageio_descriptor *, struct inode *); | ||
| 154 | int pnfs_layout_process(struct nfs4_layoutget *lgp); | 130 | int pnfs_layout_process(struct nfs4_layoutget *lgp); |
| 155 | void pnfs_free_lseg_list(struct list_head *tmp_list); | 131 | void pnfs_free_lseg_list(struct list_head *tmp_list); |
| 156 | void pnfs_destroy_layout(struct nfs_inode *); | 132 | void pnfs_destroy_layout(struct nfs_inode *); |
| @@ -177,6 +153,16 @@ static inline int lo_fail_bit(u32 iomode) | |||
| 177 | NFS_LAYOUT_RW_FAILED : NFS_LAYOUT_RO_FAILED; | 153 | NFS_LAYOUT_RW_FAILED : NFS_LAYOUT_RO_FAILED; |
| 178 | } | 154 | } |
| 179 | 155 | ||
| 156 | static inline struct pnfs_layout_segment * | ||
| 157 | get_lseg(struct pnfs_layout_segment *lseg) | ||
| 158 | { | ||
| 159 | if (lseg) { | ||
| 160 | atomic_inc(&lseg->pls_refcount); | ||
| 161 | smp_mb__after_atomic_inc(); | ||
| 162 | } | ||
| 163 | return lseg; | ||
| 164 | } | ||
| 165 | |||
| 180 | /* Return true if a layout driver is being used for this mountpoint */ | 166 | /* Return true if a layout driver is being used for this mountpoint */ |
| 181 | static inline int pnfs_enabled_sb(struct nfs_server *nfss) | 167 | static inline int pnfs_enabled_sb(struct nfs_server *nfss) |
| 182 | { | 168 | { |
| @@ -194,12 +180,36 @@ static inline void pnfs_destroy_layout(struct nfs_inode *nfsi) | |||
| 194 | } | 180 | } |
| 195 | 181 | ||
| 196 | static inline struct pnfs_layout_segment * | 182 | static inline struct pnfs_layout_segment * |
| 183 | get_lseg(struct pnfs_layout_segment *lseg) | ||
| 184 | { | ||
| 185 | return NULL; | ||
| 186 | } | ||
| 187 | |||
| 188 | static inline void put_lseg(struct pnfs_layout_segment *lseg) | ||
| 189 | { | ||
| 190 | } | ||
| 191 | |||
| 192 | static inline struct pnfs_layout_segment * | ||
| 197 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, | 193 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, |
| 198 | enum pnfs_iomode access_type) | 194 | enum pnfs_iomode access_type) |
| 199 | { | 195 | { |
| 200 | return NULL; | 196 | return NULL; |
| 201 | } | 197 | } |
| 202 | 198 | ||
| 199 | static inline enum pnfs_try_status | ||
| 200 | pnfs_try_to_read_data(struct nfs_read_data *data, | ||
| 201 | const struct rpc_call_ops *call_ops) | ||
| 202 | { | ||
| 203 | return PNFS_NOT_ATTEMPTED; | ||
| 204 | } | ||
| 205 | |||
| 206 | static inline enum pnfs_try_status | ||
| 207 | pnfs_try_to_write_data(struct nfs_write_data *data, | ||
| 208 | const struct rpc_call_ops *call_ops, int how) | ||
| 209 | { | ||
| 210 | return PNFS_NOT_ATTEMPTED; | ||
| 211 | } | ||
| 212 | |||
| 203 | static inline bool | 213 | static inline bool |
| 204 | pnfs_roc(struct inode *ino) | 214 | pnfs_roc(struct inode *ino) |
| 205 | { | 215 | { |
| @@ -230,6 +240,18 @@ static inline void unset_pnfs_layoutdriver(struct nfs_server *s) | |||
| 230 | { | 240 | { |
| 231 | } | 241 | } |
| 232 | 242 | ||
| 243 | static inline void | ||
| 244 | pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *ino) | ||
| 245 | { | ||
| 246 | pgio->pg_test = NULL; | ||
| 247 | } | ||
| 248 | |||
| 249 | static inline void | ||
| 250 | pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *ino) | ||
| 251 | { | ||
| 252 | pgio->pg_test = NULL; | ||
| 253 | } | ||
| 254 | |||
| 233 | #endif /* CONFIG_NFS_V4_1 */ | 255 | #endif /* CONFIG_NFS_V4_1 */ |
| 234 | 256 | ||
| 235 | #endif /* FS_NFS_PNFS_H */ | 257 | #endif /* FS_NFS_PNFS_H */ |
