]> git.pld-linux.org Git - packages/kernel.git/blob - ocfs2_2.6.22.14_fixes-20071127-1.patch
This commit was manufactured by cvs2git to create branch 'LINUX_2_6_22'.
[packages/kernel.git] / ocfs2_2.6.22.14_fixes-20071127-1.patch
1 diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
2 index 0b229a9..27a7fef 100644
3 --- a/fs/ocfs2/cluster/tcp.c
4 +++ b/fs/ocfs2/cluster/tcp.c
5 @@ -859,17 +859,25 @@ static void o2net_sendpage(struct o2net_sock_container *sc,
6         struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
7         ssize_t ret;
8  
9 -
10 -       mutex_lock(&sc->sc_send_lock);
11 -       ret = sc->sc_sock->ops->sendpage(sc->sc_sock,
12 -                                        virt_to_page(kmalloced_virt),
13 -                                        (long)kmalloced_virt & ~PAGE_MASK,
14 -                                        size, MSG_DONTWAIT);
15 -       mutex_unlock(&sc->sc_send_lock);
16 -       if (ret != size) {
17 +       while (1) {
18 +               mutex_lock(&sc->sc_send_lock);
19 +               ret = sc->sc_sock->ops->sendpage(sc->sc_sock,
20 +                                                virt_to_page(kmalloced_virt),
21 +                                                (long)kmalloced_virt & ~PAGE_MASK,
22 +                                                size, MSG_DONTWAIT);
23 +               mutex_unlock(&sc->sc_send_lock);
24 +               if (ret == size)
25 +                       break;
26 +               if (ret == (ssize_t)-EAGAIN) {
27 +                       mlog(0, "sendpage of size %zu to " SC_NODEF_FMT
28 +                            " returned EAGAIN\n", size, SC_NODEF_ARGS(sc));
29 +                       cond_resched();
30 +                       continue;
31 +               }
32                 mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT 
33                      " failed with %zd\n", size, SC_NODEF_ARGS(sc), ret);
34                 o2net_ensure_shutdown(nn, sc, 0);
35 +               break;
36         }
37  }
38  
39 diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
40 index e0cd750..fb72cd5 100644
41 --- a/fs/ocfs2/file.c
42 +++ b/fs/ocfs2/file.c
43 @@ -186,6 +186,7 @@ int ocfs2_update_inode_atime(struct inode *inode,
44         int ret;
45         struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
46         handle_t *handle;
47 +       struct ocfs2_dinode *di = (struct ocfs2_dinode *) bh->b_data;
48  
49         mlog_entry_void();
50  
51 @@ -196,11 +197,27 @@ int ocfs2_update_inode_atime(struct inode *inode,
52                 goto out;
53         }
54  
55 +       ret = ocfs2_journal_access(handle, inode, bh,
56 +                                  OCFS2_JOURNAL_ACCESS_WRITE);
57 +       if (ret) {
58 +               mlog_errno(ret);
59 +               goto out_commit;
60 +       }
61 +
62 +       /*
63 +        * Don't use ocfs2_mark_inode_dirty() here as we don't always
64 +        * have i_mutex to guard against concurrent changes to other
65 +        * inode fields.
66 +        */
67         inode->i_atime = CURRENT_TIME;
68 -       ret = ocfs2_mark_inode_dirty(handle, inode, bh);
69 +       di->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
70 +       di->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
71 +
72 +       ret = ocfs2_journal_dirty(handle, bh);
73         if (ret < 0)
74                 mlog_errno(ret);
75  
76 +out_commit:
77         ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
78  out:
79         mlog_exit(ret);
80 @@ -976,6 +993,11 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
81         }
82  
83         if (size_change && attr->ia_size != i_size_read(inode)) {
84 +               if (attr->ia_size > sb->s_maxbytes) {
85 +                       status = -EFBIG;
86 +                       goto bail_unlock;
87 +               }
88 +
89                 if (i_size_read(inode) > attr->ia_size)
90                         status = ocfs2_truncate_file(inode, bh, attr->ia_size);
91                 else
92 diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
93 index 36289e6..b22c169 100644
94 --- a/fs/ocfs2/namei.c
95 +++ b/fs/ocfs2/namei.c
96 @@ -1080,6 +1080,7 @@ static int ocfs2_rename(struct inode *old_dir,
97         struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
98                                                     // this is the 1st dirent bh
99         nlink_t old_dir_nlink = old_dir->i_nlink;
100 +       struct ocfs2_dinode *old_di;
101  
102         /* At some point it might be nice to break this function up a
103          * bit. */
104 @@ -1354,7 +1355,20 @@ static int ocfs2_rename(struct inode *old_dir,
105  
106         old_inode->i_ctime = CURRENT_TIME;
107         mark_inode_dirty(old_inode);
108 -       ocfs2_mark_inode_dirty(handle, old_inode, old_inode_bh);
109 +
110 +       status = ocfs2_journal_access(handle, old_inode, old_inode_bh,
111 +                                     OCFS2_JOURNAL_ACCESS_WRITE);
112 +       if (status >= 0) {
113 +               old_di = (struct ocfs2_dinode *) old_inode_bh->b_data;
114 +
115 +               old_di->i_ctime = cpu_to_le64(old_inode->i_ctime.tv_sec);
116 +               old_di->i_ctime_nsec = cpu_to_le32(old_inode->i_ctime.tv_nsec);
117 +
118 +               status = ocfs2_journal_dirty(handle, old_inode_bh);
119 +               if (status < 0)
120 +                       mlog_errno(status);
121 +       } else
122 +               mlog_errno(status);
123  
124         /* now that the name has been added to new_dir, remove the old name */
125         status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh);
126 diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
127 index a860633..0367108 100644
128 --- a/fs/ocfs2/ocfs2.h
129 +++ b/fs/ocfs2/ocfs2.h
130 @@ -480,16 +480,16 @@ static inline unsigned int ocfs2_page_index_to_clusters(struct super_block *sb,
131  /*
132   * Find the 1st page index which covers the given clusters.
133   */
134 -static inline unsigned long ocfs2_align_clusters_to_page_index(struct super_block *sb,
135 +static inline pgoff_t ocfs2_align_clusters_to_page_index(struct super_block *sb,
136                                                         u32 clusters)
137  {
138         unsigned int cbits = OCFS2_SB(sb)->s_clustersize_bits;
139 -       unsigned long index = clusters;
140 +        pgoff_t index = clusters;
141  
142         if (PAGE_CACHE_SHIFT > cbits) {
143 -               index = clusters >> (PAGE_CACHE_SHIFT - cbits);
144 +               index = (pgoff_t)clusters >> (PAGE_CACHE_SHIFT - cbits);
145         } else if (PAGE_CACHE_SHIFT < cbits) {
146 -               index = clusters << (cbits - PAGE_CACHE_SHIFT);
147 +               index = (pgoff_t)clusters << (cbits - PAGE_CACHE_SHIFT);
148         }
149  
150         return index;
151 diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
152 index 86b559c..07a4579 100644
153 --- a/fs/ocfs2/super.c
154 +++ b/fs/ocfs2/super.c
155 @@ -114,8 +114,6 @@ static void ocfs2_write_super(struct super_block *sb);
156  static struct inode *ocfs2_alloc_inode(struct super_block *sb);
157  static void ocfs2_destroy_inode(struct inode *inode);
158  
159 -static unsigned long long ocfs2_max_file_offset(unsigned int blockshift);
160 -
161  static const struct super_operations ocfs2_sops = {
162         .statfs         = ocfs2_statfs,
163         .alloc_inode    = ocfs2_alloc_inode,
164 @@ -315,39 +313,51 @@ static void ocfs2_destroy_inode(struct inode *inode)
165         kmem_cache_free(ocfs2_inode_cachep, OCFS2_I(inode));
166  }
167  
168 -/* From xfs_super.c:xfs_max_file_offset
169 - * Copyright (c) 2000-2004 Silicon Graphics, Inc.
170 - */
171 -static unsigned long long ocfs2_max_file_offset(unsigned int blockshift)
172 +static unsigned long long ocfs2_max_file_offset(unsigned int bbits,
173 +                                               unsigned int cbits)
174  {
175 -       unsigned int pagefactor = 1;
176 -       unsigned int bitshift = BITS_PER_LONG - 1;
177 -
178 -       /* Figure out maximum filesize, on Linux this can depend on
179 -        * the filesystem blocksize (on 32 bit platforms).
180 -        * __block_prepare_write does this in an [unsigned] long...
181 -        *      page->index << (PAGE_CACHE_SHIFT - bbits)
182 -        * So, for page sized blocks (4K on 32 bit platforms),
183 -        * this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is
184 -        *      (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
185 -        * but for smaller blocksizes it is less (bbits = log2 bsize).
186 -        * Note1: get_block_t takes a long (implicit cast from above)
187 -        * Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch
188 -        * can optionally convert the [unsigned] long from above into
189 -        * an [unsigned] long long.
190 +       unsigned int bytes = 1 << cbits;
191 +       unsigned int trim = bytes;
192 +       unsigned int bitshift = 32;
193 +
194 +       /*
195 +        * i_size and all block offsets in ocfs2 are always 64 bits
196 +        * wide. i_clusters is 32 bits, in cluster-sized units. So on
197 +        * 64 bit platforms, cluster size will be the limiting factor.
198          */
199  
200  #if BITS_PER_LONG == 32
201  # if defined(CONFIG_LBD)
202         BUILD_BUG_ON(sizeof(sector_t) != 8);
203 -       pagefactor = PAGE_CACHE_SIZE;
204 -       bitshift = BITS_PER_LONG;
205 +       /*
206 +        * We might be limited by page cache size.
207 +        */
208 +       if (bytes > PAGE_CACHE_SIZE) {
209 +               bytes = PAGE_CACHE_SIZE;
210 +               trim = 1;
211 +               /*
212 +                * Shift by 31 here so that we don't get larger than
213 +                * MAX_LFS_FILESIZE
214 +                */
215 +               bitshift = 31;
216 +       }
217  # else
218 -       pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift);
219 +       /*
220 +        * We are limited by the size of sector_t. Use block size, as
221 +        * that's what we expose to the VFS.
222 +        */
223 +       bytes = 1 << bbits;
224 +       trim = 1;
225 +       bitshift = 31;
226  # endif
227  #endif
228  
229 -       return (((unsigned long long)pagefactor) << bitshift) - 1;
230 +       /*
231 +        * Trim by a whole cluster when we can actually approach the
232 +        * on-disk limits. Otherwise we can overflow i_clusters when
233 +        * an extent start is at the max offset.
234 +        */
235 +       return (((unsigned long long)bytes) << bitshift) - trim;
236  }
237  
238  static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
239 @@ -1244,8 +1254,8 @@ static int ocfs2_initialize_super(struct super_block *sb,
240                                   int sector_size)
241  {
242         int status = 0;
243 -       int i;
244 -       struct ocfs2_dinode *di = NULL;
245 +       int i, cbits, bbits;
246 +       struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
247         struct inode *inode = NULL;
248         struct buffer_head *bitmap_bh = NULL;
249         struct ocfs2_journal *journal;
250 @@ -1264,9 +1274,12 @@ static int ocfs2_initialize_super(struct super_block *sb,
251         sb->s_fs_info = osb;
252         sb->s_op = &ocfs2_sops;
253         sb->s_export_op = &ocfs2_export_ops;
254 +       sb->s_time_gran = 1;
255         sb->s_flags |= MS_NOATIME;
256         /* this is needed to support O_LARGEFILE */
257 -       sb->s_maxbytes = ocfs2_max_file_offset(sb->s_blocksize_bits);
258 +       cbits = le32_to_cpu(di->id2.i_super.s_clustersize_bits);
259 +       bbits = le32_to_cpu(di->id2.i_super.s_blocksize_bits);
260 +       sb->s_maxbytes = ocfs2_max_file_offset(bbits, cbits);
261  
262         osb->sb = sb;
263         /* Save off for ocfs2_rw_direct */
264 @@ -1326,8 +1339,6 @@ static int ocfs2_initialize_super(struct super_block *sb,
265                 goto bail;
266         }
267  
268 -       di = (struct ocfs2_dinode *)bh->b_data;
269 -
270         osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots);
271         if (osb->max_slots > OCFS2_MAX_SLOTS || osb->max_slots == 0) {
272                 mlog(ML_ERROR, "Invalid number of node slots (%u)\n",
This page took 0.731864 seconds and 3 git commands to generate.