Skip to content

Commit cd1acdf

Browse files
committed
Merge branch 'pnfs-submit' of git://git.open-osd.org/linux-open-osd
* 'pnfs-submit' of git://git.open-osd.org/linux-open-osd: (32 commits) pnfs-obj: pg_test check for max_io_size NFSv4.1: define nfs_generic_pg_test NFSv4.1: use pnfs_generic_pg_test directly by layout driver NFSv4.1: change pg_test return type to bool NFSv4.1: unify pnfs_pageio_init functions pnfs-obj: objlayout_encode_layoutcommit implementation pnfs: encode_layoutcommit pnfs-obj: report errors and .encode_layoutreturn Implementation. pnfs: encode_layoutreturn pnfs: layoutret_on_setattr pnfs: layoutreturn pnfs-obj: osd raid engine read/write implementation pnfs: support for non-rpc layout drivers pnfs-obj: define per-inode private structure pnfs: alloc and free layout_hdr layoutdriver methods pnfs-obj: objio_osd device information retrieval and caching pnfs-obj: decode layout, alloc/free lseg pnfs-obj: pnfs_osd XDR client implementation pnfs-obj: pnfs_osd XDR definitions pnfs-obj: objlayoutdriver module skeleton ...
2 parents fac0486 + 9342077 commit cd1acdf

32 files changed

+3907
-279
lines changed

fs/nfs/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,16 @@ config NFS_V4_1
8787
config PNFS_FILE_LAYOUT
8888
tristate
8989

90+
config PNFS_OBJLAYOUT
91+
tristate "Provide support for the pNFS Objects Layout Driver for NFSv4.1 pNFS (EXPERIMENTAL)"
92+
depends on NFS_FS && NFS_V4_1 && SCSI_OSD_ULD
93+
help
94+
Say M here if you want your pNFS client to support the Objects Layout Driver.
95+
Requires the SCSI osd initiator library (SCSI_OSD_INITIATOR) and
96+
upper level driver (SCSI_OSD_ULD).
97+
98+
If unsure, say N.
99+
90100
config ROOT_NFS
91101
bool "Root file system on NFS"
92102
depends on NFS_FS=y && IP_PNP

fs/nfs/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
1515
delegation.o idmap.o \
1616
callback.o callback_xdr.o callback_proc.o \
1717
nfs4namespace.o
18-
nfs-$(CONFIG_NFS_V4_1) += pnfs.o
18+
nfs-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o
1919
nfs-$(CONFIG_SYSCTL) += sysctl.o
2020
nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
2121

2222
obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o
2323
nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o
24+
25+
obj-$(CONFIG_PNFS_OBJLAYOUT) += objlayout/

fs/nfs/callback.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,23 @@ extern unsigned nfs4_callback_layoutrecall(
167167

168168
extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses);
169169
extern void nfs4_cb_take_slot(struct nfs_client *clp);
170+
171+
struct cb_devicenotifyitem {
172+
uint32_t cbd_notify_type;
173+
uint32_t cbd_layout_type;
174+
struct nfs4_deviceid cbd_dev_id;
175+
uint32_t cbd_immediate;
176+
};
177+
178+
struct cb_devicenotifyargs {
179+
int ndevs;
180+
struct cb_devicenotifyitem *devs;
181+
};
182+
183+
extern __be32 nfs4_callback_devicenotify(
184+
struct cb_devicenotifyargs *args,
185+
void *dummy, struct cb_process_state *cps);
186+
170187
#endif /* CONFIG_NFS_V4_1 */
171188
extern int check_gss_callback_principal(struct nfs_client *, struct svc_rqst *);
172189
extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args,

fs/nfs/callback_proc.c

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ static u32 initiate_file_draining(struct nfs_client *clp,
139139
spin_lock(&ino->i_lock);
140140
if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) ||
141141
mark_matching_lsegs_invalid(lo, &free_me_list,
142-
args->cbl_range.iomode))
142+
&args->cbl_range))
143143
rv = NFS4ERR_DELAY;
144144
else
145145
rv = NFS4ERR_NOMATCHING_LAYOUT;
@@ -184,7 +184,7 @@ static u32 initiate_bulk_draining(struct nfs_client *clp,
184184
ino = lo->plh_inode;
185185
spin_lock(&ino->i_lock);
186186
set_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags);
187-
if (mark_matching_lsegs_invalid(lo, &free_me_list, range.iomode))
187+
if (mark_matching_lsegs_invalid(lo, &free_me_list, &range))
188188
rv = NFS4ERR_DELAY;
189189
list_del_init(&lo->plh_bulk_recall);
190190
spin_unlock(&ino->i_lock);
@@ -241,6 +241,53 @@ static void pnfs_recall_all_layouts(struct nfs_client *clp)
241241
do_callback_layoutrecall(clp, &args);
242242
}
243243

244+
__be32 nfs4_callback_devicenotify(struct cb_devicenotifyargs *args,
245+
void *dummy, struct cb_process_state *cps)
246+
{
247+
int i;
248+
__be32 res = 0;
249+
struct nfs_client *clp = cps->clp;
250+
struct nfs_server *server = NULL;
251+
252+
dprintk("%s: -->\n", __func__);
253+
254+
if (!clp) {
255+
res = cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION);
256+
goto out;
257+
}
258+
259+
for (i = 0; i < args->ndevs; i++) {
260+
struct cb_devicenotifyitem *dev = &args->devs[i];
261+
262+
if (!server ||
263+
server->pnfs_curr_ld->id != dev->cbd_layout_type) {
264+
rcu_read_lock();
265+
list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
266+
if (server->pnfs_curr_ld &&
267+
server->pnfs_curr_ld->id == dev->cbd_layout_type) {
268+
rcu_read_unlock();
269+
goto found;
270+
}
271+
rcu_read_unlock();
272+
dprintk("%s: layout type %u not found\n",
273+
__func__, dev->cbd_layout_type);
274+
continue;
275+
}
276+
277+
found:
278+
if (dev->cbd_notify_type == NOTIFY_DEVICEID4_CHANGE)
279+
dprintk("%s: NOTIFY_DEVICEID4_CHANGE not supported, "
280+
"deleting instead\n", __func__);
281+
nfs4_delete_deviceid(server->pnfs_curr_ld, clp, &dev->cbd_dev_id);
282+
}
283+
284+
out:
285+
kfree(args->devs);
286+
dprintk("%s: exit with status = %u\n",
287+
__func__, be32_to_cpu(res));
288+
return res;
289+
}
290+
244291
int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const nfs4_stateid *stateid)
245292
{
246293
if (delegation == NULL)

fs/nfs/callback_xdr.c

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#if defined(CONFIG_NFS_V4_1)
2727
#define CB_OP_LAYOUTRECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
28+
#define CB_OP_DEVICENOTIFY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
2829
#define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \
2930
4 + 1 + 3)
3031
#define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
@@ -284,6 +285,93 @@ static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp,
284285
return status;
285286
}
286287

288+
static
289+
__be32 decode_devicenotify_args(struct svc_rqst *rqstp,
290+
struct xdr_stream *xdr,
291+
struct cb_devicenotifyargs *args)
292+
{
293+
__be32 *p;
294+
__be32 status = 0;
295+
u32 tmp;
296+
int n, i;
297+
args->ndevs = 0;
298+
299+
/* Num of device notifications */
300+
p = read_buf(xdr, sizeof(uint32_t));
301+
if (unlikely(p == NULL)) {
302+
status = htonl(NFS4ERR_BADXDR);
303+
goto out;
304+
}
305+
n = ntohl(*p++);
306+
if (n <= 0)
307+
goto out;
308+
309+
args->devs = kmalloc(n * sizeof(*args->devs), GFP_KERNEL);
310+
if (!args->devs) {
311+
status = htonl(NFS4ERR_DELAY);
312+
goto out;
313+
}
314+
315+
/* Decode each dev notification */
316+
for (i = 0; i < n; i++) {
317+
struct cb_devicenotifyitem *dev = &args->devs[i];
318+
319+
p = read_buf(xdr, (4 * sizeof(uint32_t)) + NFS4_DEVICEID4_SIZE);
320+
if (unlikely(p == NULL)) {
321+
status = htonl(NFS4ERR_BADXDR);
322+
goto err;
323+
}
324+
325+
tmp = ntohl(*p++); /* bitmap size */
326+
if (tmp != 1) {
327+
status = htonl(NFS4ERR_INVAL);
328+
goto err;
329+
}
330+
dev->cbd_notify_type = ntohl(*p++);
331+
if (dev->cbd_notify_type != NOTIFY_DEVICEID4_CHANGE &&
332+
dev->cbd_notify_type != NOTIFY_DEVICEID4_DELETE) {
333+
status = htonl(NFS4ERR_INVAL);
334+
goto err;
335+
}
336+
337+
tmp = ntohl(*p++); /* opaque size */
338+
if (((dev->cbd_notify_type == NOTIFY_DEVICEID4_CHANGE) &&
339+
(tmp != NFS4_DEVICEID4_SIZE + 8)) ||
340+
((dev->cbd_notify_type == NOTIFY_DEVICEID4_DELETE) &&
341+
(tmp != NFS4_DEVICEID4_SIZE + 4))) {
342+
status = htonl(NFS4ERR_INVAL);
343+
goto err;
344+
}
345+
dev->cbd_layout_type = ntohl(*p++);
346+
memcpy(dev->cbd_dev_id.data, p, NFS4_DEVICEID4_SIZE);
347+
p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE);
348+
349+
if (dev->cbd_layout_type == NOTIFY_DEVICEID4_CHANGE) {
350+
p = read_buf(xdr, sizeof(uint32_t));
351+
if (unlikely(p == NULL)) {
352+
status = htonl(NFS4ERR_BADXDR);
353+
goto err;
354+
}
355+
dev->cbd_immediate = ntohl(*p++);
356+
} else {
357+
dev->cbd_immediate = 0;
358+
}
359+
360+
args->ndevs++;
361+
362+
dprintk("%s: type %d layout 0x%x immediate %d\n",
363+
__func__, dev->cbd_notify_type, dev->cbd_layout_type,
364+
dev->cbd_immediate);
365+
}
366+
out:
367+
dprintk("%s: status %d ndevs %d\n",
368+
__func__, ntohl(status), args->ndevs);
369+
return status;
370+
err:
371+
kfree(args->devs);
372+
goto out;
373+
}
374+
287375
static __be32 decode_sessionid(struct xdr_stream *xdr,
288376
struct nfs4_sessionid *sid)
289377
{
@@ -639,10 +727,10 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
639727
case OP_CB_RECALL_ANY:
640728
case OP_CB_RECALL_SLOT:
641729
case OP_CB_LAYOUTRECALL:
730+
case OP_CB_NOTIFY_DEVICEID:
642731
*op = &callback_ops[op_nr];
643732
break;
644733

645-
case OP_CB_NOTIFY_DEVICEID:
646734
case OP_CB_NOTIFY:
647735
case OP_CB_PUSH_DELEG:
648736
case OP_CB_RECALLABLE_OBJ_AVAIL:
@@ -849,6 +937,12 @@ static struct callback_op callback_ops[] = {
849937
(callback_decode_arg_t)decode_layoutrecall_args,
850938
.res_maxsize = CB_OP_LAYOUTRECALL_RES_MAXSZ,
851939
},
940+
[OP_CB_NOTIFY_DEVICEID] = {
941+
.process_op = (callback_process_op_t)nfs4_callback_devicenotify,
942+
.decode_args =
943+
(callback_decode_arg_t)decode_devicenotify_args,
944+
.res_maxsize = CB_OP_DEVICENOTIFY_RES_MAXSZ,
945+
},
852946
[OP_CB_SEQUENCE] = {
853947
.process_op = (callback_process_op_t)nfs4_callback_sequence,
854948
.decode_args = (callback_decode_arg_t)decode_cb_sequence_args,

fs/nfs/client.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,8 @@ static void nfs_free_client(struct nfs_client *clp)
290290
if (clp->cl_machine_cred != NULL)
291291
put_rpccred(clp->cl_machine_cred);
292292

293+
nfs4_deviceid_purge_client(clp);
294+
293295
kfree(clp->cl_hostname);
294296
kfree(clp);
295297

fs/nfs/dir.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -512,12 +512,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
512512
struct page **xdr_pages, struct page *page, unsigned int buflen)
513513
{
514514
struct xdr_stream stream;
515-
struct xdr_buf buf = {
516-
.pages = xdr_pages,
517-
.page_len = buflen,
518-
.buflen = buflen,
519-
.len = buflen,
520-
};
515+
struct xdr_buf buf;
521516
struct page *scratch;
522517
struct nfs_cache_array *array;
523518
unsigned int count = 0;
@@ -527,7 +522,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
527522
if (scratch == NULL)
528523
return -ENOMEM;
529524

530-
xdr_init_decode(&stream, &buf, NULL);
525+
xdr_init_decode_pages(&stream, &buf, xdr_pages, buflen);
531526
xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
532527

533528
do {

fs/nfs/inode.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1428,9 +1428,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
14281428
*/
14291429
void nfs4_evict_inode(struct inode *inode)
14301430
{
1431-
pnfs_destroy_layout(NFS_I(inode));
14321431
truncate_inode_pages(&inode->i_data, 0);
14331432
end_writeback(inode);
1433+
pnfs_return_layout(inode);
1434+
pnfs_destroy_layout(NFS_I(inode));
14341435
/* If we are holding a delegation, return it! */
14351436
nfs_inode_return_delegation_noreclaim(inode);
14361437
/* First call standard NFS clear_inode() code */

fs/nfs/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ extern int nfs_migrate_page(struct address_space *,
310310
#endif
311311

312312
/* nfs4proc.c */
313+
extern void __nfs4_read_done_cb(struct nfs_read_data *);
313314
extern void nfs4_reset_read(struct rpc_task *task, struct nfs_read_data *data);
314315
extern int nfs4_init_client(struct nfs_client *clp,
315316
const struct rpc_timeout *timeparms,

0 commit comments

Comments
 (0)