summaryrefslogtreecommitdiff
path: root/fs/ocfs2/aops.c
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2007-09-17 09:06:29 -0700
committerMark Fasheh <mark.fasheh@oracle.com>2007-09-20 15:06:09 -0700
commitdb56246c6980e376b02d2da568d119da71f82fb9 (patch)
treedc88e09c80d50dd77580d1d9366bac8c74c9bffa /fs/ocfs2/aops.c
parent415cb800375cc4e89fb5a6a454e484bd4adbffb4 (diff)
downloadlinux-3.10-db56246c6980e376b02d2da568d119da71f82fb9.tar.gz
linux-3.10-db56246c6980e376b02d2da568d119da71f82fb9.tar.bz2
linux-3.10-db56246c6980e376b02d2da568d119da71f82fb9.zip
ocfs2: Fix pos/len passed to ocfs2_write_cluster
This was broken for file systems whose cluster size is greater than page size. Pos needs to be incremented as we loop through the descriptors, and len needs to be capped to the size of a single cluster. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r--fs/ocfs2/aops.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 50cd8a20901..fa43810e597 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1211,18 +1211,33 @@ static int ocfs2_write_cluster_by_desc(struct address_space *mapping,
loff_t pos, unsigned len)
{
int ret, i;
+ loff_t cluster_off;
+ unsigned int local_len = len;
struct ocfs2_write_cluster_desc *desc;
+ struct ocfs2_super *osb = OCFS2_SB(mapping->host->i_sb);
for (i = 0; i < wc->w_clen; i++) {
desc = &wc->w_desc[i];
+ /*
+ * We have to make sure that the total write passed in
+ * doesn't extend past a single cluster.
+ */
+ local_len = len;
+ cluster_off = pos & (osb->s_clustersize - 1);
+ if ((cluster_off + local_len) > osb->s_clustersize)
+ local_len = osb->s_clustersize - cluster_off;
+
ret = ocfs2_write_cluster(mapping, desc->c_phys,
desc->c_unwritten, data_ac, meta_ac,
- wc, desc->c_cpos, pos, len);
+ wc, desc->c_cpos, pos, local_len);
if (ret) {
mlog_errno(ret);
goto out;
}
+
+ len -= local_len;
+ pos += local_len;
}
ret = 0;