Whamcloud - gitweb
git://git.whamcloud.com
/
fs
/
lustre-release.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
| inline |
side by side
b=21982 long file truncate problem
[fs/lustre-release.git]
/
lustre
/
llite
/
vvp_io.c
diff --git
a/lustre/llite/vvp_io.c
b/lustre/llite/vvp_io.c
index
a29574c
..
89bb048
100644
(file)
--- a/
lustre/llite/vvp_io.c
+++ b/
lustre/llite/vvp_io.c
@@
-293,7
+293,7
@@
static int vvp_io_trunc_lock(const struct lu_env *env,
{
struct ccc_io *vio = cl2ccc_io(env, ios);
struct cl_io *io = ios->cis_io;
-
size
_t new_size = io->u.ci_truncate.tr_size;
+
loff
_t new_size = io->u.ci_truncate.tr_size;
__u32 enqflags = new_size == 0 ? CEF_DISCARD_DATA : 0;
int result;
@@
-303,6
+303,22
@@
static int vvp_io_trunc_lock(const struct lu_env *env,
return result;
}
+static int vvp_do_vmtruncate(struct inode *inode, size_t size)
+{
+ int result;
+ /*
+ * Only ll_inode_size_lock is taken at this level. lov_stripe_lock()
+ * is grabbed by ll_truncate() only over call to obd_adjust_kms(). If
+ * vmtruncate returns 0, then ll_truncate dropped ll_inode_size_lock()
+ */
+ ll_inode_size_lock(inode, 0);
+ result = vmtruncate(inode, size);
+ if (result != 0)
+ ll_inode_size_unlock(inode, 0);
+
+ return result;
+}
+
static int vvp_io_trunc_start(const struct lu_env *env,
const struct cl_io_slice *ios)
{
@@
-311,7
+327,7
@@
static int vvp_io_trunc_start(const struct lu_env *env,
struct cl_io *io = ios->cis_io;
struct inode *inode = ccc_object_inode(io->ci_obj);
struct cl_object *obj = ios->cis_obj;
-
size
_t size = io->u.ci_truncate.tr_size;
+
loff
_t size = io->u.ci_truncate.tr_size;
pgoff_t start = cl_index(obj, size);
int result;
@@
-321,15
+337,8
@@
static int vvp_io_trunc_start(const struct lu_env *env,
DOWN_WRITE_I_ALLOC_SEM(inode);
cio->u.trunc.cui_locks_released = 0;
- /*
- * Only ll_inode_size_lock is taken at this level. lov_stripe_lock()
- * is grabbed by ll_truncate() only over call to obd_adjust_kms(). If
- * vmtruncate returns 0, then ll_truncate dropped ll_inode_size_lock()
- */
- ll_inode_size_lock(inode, 0);
- result = vmtruncate(inode, size);
- if (result != 0)
- ll_inode_size_unlock(inode, 0);
+ result = vvp_do_vmtruncate(inode, size);
+
/*
* If a page is partially truncated, keep it owned across truncate to
* prevent... races.
@@
-341,9
+350,9
@@
static int vvp_io_trunc_start(const struct lu_env *env,
struct cl_object_header *hdr;
hdr = cl_object_header(obj);
- spin_lock(&hdr->coh_page_guard);
+
cfs_
spin_lock(&hdr->coh_page_guard);
vio->cui_partpage = cl_page_lookup(hdr, start);
- spin_unlock(&hdr->coh_page_guard);
+
cfs_
spin_unlock(&hdr->coh_page_guard);
if (vio->cui_partpage != NULL)
/*
@@
-363,13
+372,22
@@
static int vvp_io_trunc_start(const struct lu_env *env,
static void vvp_io_trunc_end(const struct lu_env *env,
const struct cl_io_slice *ios)
{
- struct vvp_io *vio = cl2vvp_io(env, ios);
+ struct vvp_io *vio = cl2vvp_io(env, ios);
+ struct cl_io *io = ios->cis_io;
+ struct inode *inode = ccc_object_inode(io->ci_obj);
+ loff_t size = io->u.ci_truncate.tr_size;
if (vio->cui_partpage != NULL) {
cl_page_disown(env, ios->cis_io, vio->cui_partpage);
cl_page_put(env, vio->cui_partpage);
vio->cui_partpage = NULL;
}
+
+ /*
+ * Do vmtruncate again, to remove possible stale pages populated by
+ * competing read threads. bz20645.
+ */
+ vvp_do_vmtruncate(inode, size);
}
static void vvp_io_trunc_fini(const struct lu_env *env,
@@
-914,12
+932,17
@@
static int vvp_io_commit_write(const struct lu_env *env,
size = cl_offset(obj, pg->cp_index) + to;
+ ll_inode_size_lock(inode, 0);
if (result == 0) {
if (size > i_size_read(inode))
-
i_size_write
(inode, size);
+
cl_isize_write_nolock
(inode, size);
cl_page_export(env, pg, 1);
- } else if (size > i_size_read(inode))
- cl_page_discard(env, io, pg);
+ } else {
+ if (size > i_size_read(inode))
+ cl_page_discard(env, io, pg);
+ }
+ ll_inode_size_unlock(inode, 0);
+
RETURN(result);
}