diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-03-20 13:23:33 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-03-21 10:31:21 -0400 |
commit | 240286725d854331422cb15957f8d9bf2741d4e3 (patch) | |
tree | 2b92c0f41ef7e303dd26f976a8afcdae467b08f0 /fs | |
parent | 24956804349ca0eadcdde032d65e8c00b4214096 (diff) |
NFSv4.1: Add a helper pnfs_commit_and_return_layout
In order to be able to safely return the layout in nfs4_proc_setattr,
we need to block new uses of the layout, wait for all outstanding
users of the layout to complete, commit the layout and then return it.
This patch adds a helper in order to do all this safely.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: Boaz Harrosh <bharrosh@panasas.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 2 | ||||
-rw-r--r-- | fs/nfs/pnfs.c | 27 | ||||
-rw-r--r-- | fs/nfs/pnfs.h | 6 |
3 files changed, 34 insertions, 1 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 6ccdd4fd9b59..26431cf62ddb 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2632,7 +2632,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, | |||
2632 | int status; | 2632 | int status; |
2633 | 2633 | ||
2634 | if (pnfs_ld_layoutret_on_setattr(inode)) | 2634 | if (pnfs_ld_layoutret_on_setattr(inode)) |
2635 | pnfs_return_layout(inode); | 2635 | pnfs_commit_and_return_layout(inode); |
2636 | 2636 | ||
2637 | nfs_fattr_init(fattr); | 2637 | nfs_fattr_init(fattr); |
2638 | 2638 | ||
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 5044142c1216..4bdffe0ba025 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -866,6 +866,33 @@ out: | |||
866 | } | 866 | } |
867 | EXPORT_SYMBOL_GPL(_pnfs_return_layout); | 867 | EXPORT_SYMBOL_GPL(_pnfs_return_layout); |
868 | 868 | ||
869 | int | ||
870 | pnfs_commit_and_return_layout(struct inode *inode) | ||
871 | { | ||
872 | struct pnfs_layout_hdr *lo; | ||
873 | int ret; | ||
874 | |||
875 | spin_lock(&inode->i_lock); | ||
876 | lo = NFS_I(inode)->layout; | ||
877 | if (lo == NULL) { | ||
878 | spin_unlock(&inode->i_lock); | ||
879 | return 0; | ||
880 | } | ||
881 | pnfs_get_layout_hdr(lo); | ||
882 | /* Block new layoutgets and read/write to ds */ | ||
883 | lo->plh_block_lgets++; | ||
884 | spin_unlock(&inode->i_lock); | ||
885 | filemap_fdatawait(inode->i_mapping); | ||
886 | ret = pnfs_layoutcommit_inode(inode, true); | ||
887 | if (ret == 0) | ||
888 | ret = _pnfs_return_layout(inode); | ||
889 | spin_lock(&inode->i_lock); | ||
890 | lo->plh_block_lgets--; | ||
891 | spin_unlock(&inode->i_lock); | ||
892 | pnfs_put_layout_hdr(lo); | ||
893 | return ret; | ||
894 | } | ||
895 | |||
869 | bool pnfs_roc(struct inode *ino) | 896 | bool pnfs_roc(struct inode *ino) |
870 | { | 897 | { |
871 | struct pnfs_layout_hdr *lo; | 898 | struct pnfs_layout_hdr *lo; |
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 94ba80417748..f5f8a470a647 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h | |||
@@ -219,6 +219,7 @@ void pnfs_set_layoutcommit(struct nfs_write_data *wdata); | |||
219 | void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data); | 219 | void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data); |
220 | int pnfs_layoutcommit_inode(struct inode *inode, bool sync); | 220 | int pnfs_layoutcommit_inode(struct inode *inode, bool sync); |
221 | int _pnfs_return_layout(struct inode *); | 221 | int _pnfs_return_layout(struct inode *); |
222 | int pnfs_commit_and_return_layout(struct inode *); | ||
222 | void pnfs_ld_write_done(struct nfs_write_data *); | 223 | void pnfs_ld_write_done(struct nfs_write_data *); |
223 | void pnfs_ld_read_done(struct nfs_read_data *); | 224 | void pnfs_ld_read_done(struct nfs_read_data *); |
224 | struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino, | 225 | struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino, |
@@ -407,6 +408,11 @@ static inline int pnfs_return_layout(struct inode *ino) | |||
407 | return 0; | 408 | return 0; |
408 | } | 409 | } |
409 | 410 | ||
411 | static inline int pnfs_commit_and_return_layout(struct inode *inode) | ||
412 | { | ||
413 | return 0; | ||
414 | } | ||
415 | |||
410 | static inline bool | 416 | static inline bool |
411 | pnfs_ld_layoutret_on_setattr(struct inode *inode) | 417 | pnfs_ld_layoutret_on_setattr(struct inode *inode) |
412 | { | 418 | { |