diff options
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r-- | fs/gfs2/inode.c | 406 |
1 files changed, 140 insertions, 266 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index d470e5286ecd..d122074c45e1 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -38,83 +38,12 @@ | |||
38 | #include "trans.h" | 38 | #include "trans.h" |
39 | #include "util.h" | 39 | #include "util.h" |
40 | 40 | ||
41 | /** | ||
42 | * gfs2_inode_attr_in - Copy attributes from the dinode into the VFS inode | ||
43 | * @ip: The GFS2 inode (with embedded disk inode data) | ||
44 | * @inode: The Linux VFS inode | ||
45 | * | ||
46 | */ | ||
47 | |||
48 | void gfs2_inode_attr_in(struct gfs2_inode *ip) | ||
49 | { | ||
50 | struct inode *inode = &ip->i_inode; | ||
51 | struct gfs2_dinode *di = &ip->i_di; | ||
52 | |||
53 | inode->i_ino = ip->i_num.no_addr; | ||
54 | |||
55 | switch (di->di_mode & S_IFMT) { | ||
56 | case S_IFBLK: | ||
57 | case S_IFCHR: | ||
58 | inode->i_rdev = MKDEV(di->di_major, di->di_minor); | ||
59 | break; | ||
60 | default: | ||
61 | inode->i_rdev = 0; | ||
62 | break; | ||
63 | }; | ||
64 | |||
65 | inode->i_mode = di->di_mode; | ||
66 | inode->i_nlink = di->di_nlink; | ||
67 | inode->i_uid = di->di_uid; | ||
68 | inode->i_gid = di->di_gid; | ||
69 | i_size_write(inode, di->di_size); | ||
70 | inode->i_atime.tv_sec = di->di_atime; | ||
71 | inode->i_mtime.tv_sec = di->di_mtime; | ||
72 | inode->i_ctime.tv_sec = di->di_ctime; | ||
73 | inode->i_atime.tv_nsec = 0; | ||
74 | inode->i_mtime.tv_nsec = 0; | ||
75 | inode->i_ctime.tv_nsec = 0; | ||
76 | inode->i_blocks = di->di_blocks << | ||
77 | (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); | ||
78 | |||
79 | if (di->di_flags & GFS2_DIF_IMMUTABLE) | ||
80 | inode->i_flags |= S_IMMUTABLE; | ||
81 | else | ||
82 | inode->i_flags &= ~S_IMMUTABLE; | ||
83 | |||
84 | if (di->di_flags & GFS2_DIF_APPENDONLY) | ||
85 | inode->i_flags |= S_APPEND; | ||
86 | else | ||
87 | inode->i_flags &= ~S_APPEND; | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * gfs2_inode_attr_out - Copy attributes from VFS inode into the dinode | ||
92 | * @ip: The GFS2 inode | ||
93 | * | ||
94 | * Only copy out the attributes that we want the VFS layer | ||
95 | * to be able to modify. | ||
96 | */ | ||
97 | |||
98 | void gfs2_inode_attr_out(struct gfs2_inode *ip) | ||
99 | { | ||
100 | struct inode *inode = &ip->i_inode; | ||
101 | struct gfs2_dinode *di = &ip->i_di; | ||
102 | gfs2_assert_withdraw(GFS2_SB(inode), | ||
103 | (di->di_mode & S_IFMT) == (inode->i_mode & S_IFMT)); | ||
104 | di->di_mode = inode->i_mode; | ||
105 | di->di_uid = inode->i_uid; | ||
106 | di->di_gid = inode->i_gid; | ||
107 | di->di_atime = inode->i_atime.tv_sec; | ||
108 | di->di_mtime = inode->i_mtime.tv_sec; | ||
109 | di->di_ctime = inode->i_ctime.tv_sec; | ||
110 | } | ||
111 | |||
112 | static int iget_test(struct inode *inode, void *opaque) | 41 | static int iget_test(struct inode *inode, void *opaque) |
113 | { | 42 | { |
114 | struct gfs2_inode *ip = GFS2_I(inode); | 43 | struct gfs2_inode *ip = GFS2_I(inode); |
115 | struct gfs2_inum *inum = opaque; | 44 | struct gfs2_inum_host *inum = opaque; |
116 | 45 | ||
117 | if (ip && ip->i_num.no_addr == inum->no_addr) | 46 | if (ip->i_num.no_addr == inum->no_addr) |
118 | return 1; | 47 | return 1; |
119 | 48 | ||
120 | return 0; | 49 | return 0; |
@@ -123,19 +52,20 @@ static int iget_test(struct inode *inode, void *opaque) | |||
123 | static int iget_set(struct inode *inode, void *opaque) | 52 | static int iget_set(struct inode *inode, void *opaque) |
124 | { | 53 | { |
125 | struct gfs2_inode *ip = GFS2_I(inode); | 54 | struct gfs2_inode *ip = GFS2_I(inode); |
126 | struct gfs2_inum *inum = opaque; | 55 | struct gfs2_inum_host *inum = opaque; |
127 | 56 | ||
128 | ip->i_num = *inum; | 57 | ip->i_num = *inum; |
58 | inode->i_ino = inum->no_addr; | ||
129 | return 0; | 59 | return 0; |
130 | } | 60 | } |
131 | 61 | ||
132 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum *inum) | 62 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum) |
133 | { | 63 | { |
134 | return ilookup5(sb, (unsigned long)inum->no_formal_ino, | 64 | return ilookup5(sb, (unsigned long)inum->no_formal_ino, |
135 | iget_test, inum); | 65 | iget_test, inum); |
136 | } | 66 | } |
137 | 67 | ||
138 | static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum) | 68 | static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum) |
139 | { | 69 | { |
140 | return iget5_locked(sb, (unsigned long)inum->no_formal_ino, | 70 | return iget5_locked(sb, (unsigned long)inum->no_formal_ino, |
141 | iget_test, iget_set, inum); | 71 | iget_test, iget_set, inum); |
@@ -150,7 +80,7 @@ static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum) | |||
150 | * Returns: A VFS inode, or an error | 80 | * Returns: A VFS inode, or an error |
151 | */ | 81 | */ |
152 | 82 | ||
153 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, unsigned int type) | 83 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned int type) |
154 | { | 84 | { |
155 | struct inode *inode = gfs2_iget(sb, inum); | 85 | struct inode *inode = gfs2_iget(sb, inum); |
156 | struct gfs2_inode *ip = GFS2_I(inode); | 86 | struct gfs2_inode *ip = GFS2_I(inode); |
@@ -188,7 +118,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, | |||
188 | if (unlikely(error)) | 118 | if (unlikely(error)) |
189 | goto fail_put; | 119 | goto fail_put; |
190 | 120 | ||
191 | ip->i_vn = ip->i_gl->gl_vn - 1; | 121 | set_bit(GIF_INVALID, &ip->i_flags); |
192 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); | 122 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); |
193 | if (unlikely(error)) | 123 | if (unlikely(error)) |
194 | goto fail_iopen; | 124 | goto fail_iopen; |
@@ -208,6 +138,63 @@ fail: | |||
208 | return ERR_PTR(error); | 138 | return ERR_PTR(error); |
209 | } | 139 | } |
210 | 140 | ||
141 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | ||
142 | { | ||
143 | struct gfs2_dinode_host *di = &ip->i_di; | ||
144 | const struct gfs2_dinode *str = buf; | ||
145 | |||
146 | if (ip->i_num.no_addr != be64_to_cpu(str->di_num.no_addr)) { | ||
147 | if (gfs2_consist_inode(ip)) | ||
148 | gfs2_dinode_print(ip); | ||
149 | return -EIO; | ||
150 | } | ||
151 | if (ip->i_num.no_formal_ino != be64_to_cpu(str->di_num.no_formal_ino)) | ||
152 | return -ESTALE; | ||
153 | |||
154 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); | ||
155 | ip->i_inode.i_rdev = 0; | ||
156 | switch (ip->i_inode.i_mode & S_IFMT) { | ||
157 | case S_IFBLK: | ||
158 | case S_IFCHR: | ||
159 | ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), | ||
160 | be32_to_cpu(str->di_minor)); | ||
161 | break; | ||
162 | }; | ||
163 | |||
164 | ip->i_inode.i_uid = be32_to_cpu(str->di_uid); | ||
165 | ip->i_inode.i_gid = be32_to_cpu(str->di_gid); | ||
166 | /* | ||
167 | * We will need to review setting the nlink count here in the | ||
168 | * light of the forthcoming ro bind mount work. This is a reminder | ||
169 | * to do that. | ||
170 | */ | ||
171 | ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink); | ||
172 | di->di_size = be64_to_cpu(str->di_size); | ||
173 | i_size_write(&ip->i_inode, di->di_size); | ||
174 | di->di_blocks = be64_to_cpu(str->di_blocks); | ||
175 | gfs2_set_inode_blocks(&ip->i_inode); | ||
176 | ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime); | ||
177 | ip->i_inode.i_atime.tv_nsec = 0; | ||
178 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); | ||
179 | ip->i_inode.i_mtime.tv_nsec = 0; | ||
180 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); | ||
181 | ip->i_inode.i_ctime.tv_nsec = 0; | ||
182 | |||
183 | di->di_goal_meta = be64_to_cpu(str->di_goal_meta); | ||
184 | di->di_goal_data = be64_to_cpu(str->di_goal_data); | ||
185 | di->di_generation = be64_to_cpu(str->di_generation); | ||
186 | |||
187 | di->di_flags = be32_to_cpu(str->di_flags); | ||
188 | gfs2_set_inode_flags(&ip->i_inode); | ||
189 | di->di_height = be16_to_cpu(str->di_height); | ||
190 | |||
191 | di->di_depth = be16_to_cpu(str->di_depth); | ||
192 | di->di_entries = be32_to_cpu(str->di_entries); | ||
193 | |||
194 | di->di_eattr = be64_to_cpu(str->di_eattr); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
211 | /** | 198 | /** |
212 | * gfs2_inode_refresh - Refresh the incore copy of the dinode | 199 | * gfs2_inode_refresh - Refresh the incore copy of the dinode |
213 | * @ip: The GFS2 inode | 200 | * @ip: The GFS2 inode |
@@ -229,21 +216,11 @@ int gfs2_inode_refresh(struct gfs2_inode *ip) | |||
229 | return -EIO; | 216 | return -EIO; |
230 | } | 217 | } |
231 | 218 | ||
232 | gfs2_dinode_in(&ip->i_di, dibh->b_data); | 219 | error = gfs2_dinode_in(ip, dibh->b_data); |
233 | |||
234 | brelse(dibh); | 220 | brelse(dibh); |
221 | clear_bit(GIF_INVALID, &ip->i_flags); | ||
235 | 222 | ||
236 | if (ip->i_num.no_addr != ip->i_di.di_num.no_addr) { | 223 | return error; |
237 | if (gfs2_consist_inode(ip)) | ||
238 | gfs2_dinode_print(&ip->i_di); | ||
239 | return -EIO; | ||
240 | } | ||
241 | if (ip->i_num.no_formal_ino != ip->i_di.di_num.no_formal_ino) | ||
242 | return -ESTALE; | ||
243 | |||
244 | ip->i_vn = ip->i_gl->gl_vn; | ||
245 | |||
246 | return 0; | ||
247 | } | 224 | } |
248 | 225 | ||
249 | int gfs2_dinode_dealloc(struct gfs2_inode *ip) | 226 | int gfs2_dinode_dealloc(struct gfs2_inode *ip) |
@@ -255,7 +232,7 @@ int gfs2_dinode_dealloc(struct gfs2_inode *ip) | |||
255 | 232 | ||
256 | if (ip->i_di.di_blocks != 1) { | 233 | if (ip->i_di.di_blocks != 1) { |
257 | if (gfs2_consist_inode(ip)) | 234 | if (gfs2_consist_inode(ip)) |
258 | gfs2_dinode_print(&ip->i_di); | 235 | gfs2_dinode_print(ip); |
259 | return -EIO; | 236 | return -EIO; |
260 | } | 237 | } |
261 | 238 | ||
@@ -318,14 +295,14 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
318 | u32 nlink; | 295 | u32 nlink; |
319 | int error; | 296 | int error; |
320 | 297 | ||
321 | BUG_ON(ip->i_di.di_nlink != ip->i_inode.i_nlink); | 298 | BUG_ON(diff != 1 && diff != -1); |
322 | nlink = ip->i_di.di_nlink + diff; | 299 | nlink = ip->i_inode.i_nlink + diff; |
323 | 300 | ||
324 | /* If we are reducing the nlink count, but the new value ends up being | 301 | /* If we are reducing the nlink count, but the new value ends up being |
325 | bigger than the old one, we must have underflowed. */ | 302 | bigger than the old one, we must have underflowed. */ |
326 | if (diff < 0 && nlink > ip->i_di.di_nlink) { | 303 | if (diff < 0 && nlink > ip->i_inode.i_nlink) { |
327 | if (gfs2_consist_inode(ip)) | 304 | if (gfs2_consist_inode(ip)) |
328 | gfs2_dinode_print(&ip->i_di); | 305 | gfs2_dinode_print(ip); |
329 | return -EIO; | 306 | return -EIO; |
330 | } | 307 | } |
331 | 308 | ||
@@ -333,16 +310,19 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
333 | if (error) | 310 | if (error) |
334 | return error; | 311 | return error; |
335 | 312 | ||
336 | ip->i_di.di_nlink = nlink; | 313 | if (diff > 0) |
337 | ip->i_di.di_ctime = get_seconds(); | 314 | inc_nlink(&ip->i_inode); |
338 | ip->i_inode.i_nlink = nlink; | 315 | else |
316 | drop_nlink(&ip->i_inode); | ||
317 | |||
318 | ip->i_inode.i_ctime.tv_sec = get_seconds(); | ||
339 | 319 | ||
340 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 320 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
341 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 321 | gfs2_dinode_out(ip, dibh->b_data); |
342 | brelse(dibh); | 322 | brelse(dibh); |
343 | mark_inode_dirty(&ip->i_inode); | 323 | mark_inode_dirty(&ip->i_inode); |
344 | 324 | ||
345 | if (ip->i_di.di_nlink == 0) { | 325 | if (ip->i_inode.i_nlink == 0) { |
346 | struct gfs2_rgrpd *rgd; | 326 | struct gfs2_rgrpd *rgd; |
347 | struct gfs2_holder ri_gh, rg_gh; | 327 | struct gfs2_holder ri_gh, rg_gh; |
348 | 328 | ||
@@ -357,7 +337,6 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
357 | if (error) | 337 | if (error) |
358 | goto out_norgrp; | 338 | goto out_norgrp; |
359 | 339 | ||
360 | clear_nlink(&ip->i_inode); | ||
361 | gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */ | 340 | gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */ |
362 | gfs2_glock_dq_uninit(&rg_gh); | 341 | gfs2_glock_dq_uninit(&rg_gh); |
363 | out_norgrp: | 342 | out_norgrp: |
@@ -394,7 +373,7 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | |||
394 | struct super_block *sb = dir->i_sb; | 373 | struct super_block *sb = dir->i_sb; |
395 | struct gfs2_inode *dip = GFS2_I(dir); | 374 | struct gfs2_inode *dip = GFS2_I(dir); |
396 | struct gfs2_holder d_gh; | 375 | struct gfs2_holder d_gh; |
397 | struct gfs2_inum inum; | 376 | struct gfs2_inum_host inum; |
398 | unsigned int type; | 377 | unsigned int type; |
399 | int error = 0; | 378 | int error = 0; |
400 | struct inode *inode = NULL; | 379 | struct inode *inode = NULL; |
@@ -436,7 +415,7 @@ static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino) | |||
436 | { | 415 | { |
437 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); | 416 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); |
438 | struct buffer_head *bh; | 417 | struct buffer_head *bh; |
439 | struct gfs2_inum_range ir; | 418 | struct gfs2_inum_range_host ir; |
440 | int error; | 419 | int error; |
441 | 420 | ||
442 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); | 421 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); |
@@ -479,7 +458,7 @@ static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino) | |||
479 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode); | 458 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode); |
480 | struct gfs2_holder gh; | 459 | struct gfs2_holder gh; |
481 | struct buffer_head *bh; | 460 | struct buffer_head *bh; |
482 | struct gfs2_inum_range ir; | 461 | struct gfs2_inum_range_host ir; |
483 | int error; | 462 | int error; |
484 | 463 | ||
485 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 464 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
@@ -500,21 +479,22 @@ static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino) | |||
500 | if (!ir.ir_length) { | 479 | if (!ir.ir_length) { |
501 | struct buffer_head *m_bh; | 480 | struct buffer_head *m_bh; |
502 | u64 x, y; | 481 | u64 x, y; |
482 | __be64 z; | ||
503 | 483 | ||
504 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); | 484 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); |
505 | if (error) | 485 | if (error) |
506 | goto out_brelse; | 486 | goto out_brelse; |
507 | 487 | ||
508 | x = *(u64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)); | 488 | z = *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)); |
509 | x = y = be64_to_cpu(x); | 489 | x = y = be64_to_cpu(z); |
510 | ir.ir_start = x; | 490 | ir.ir_start = x; |
511 | ir.ir_length = GFS2_INUM_QUANTUM; | 491 | ir.ir_length = GFS2_INUM_QUANTUM; |
512 | x += GFS2_INUM_QUANTUM; | 492 | x += GFS2_INUM_QUANTUM; |
513 | if (x < y) | 493 | if (x < y) |
514 | gfs2_consist_inode(m_ip); | 494 | gfs2_consist_inode(m_ip); |
515 | x = cpu_to_be64(x); | 495 | z = cpu_to_be64(x); |
516 | gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); | 496 | gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); |
517 | *(u64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = x; | 497 | *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = z; |
518 | 498 | ||
519 | brelse(m_bh); | 499 | brelse(m_bh); |
520 | } | 500 | } |
@@ -567,7 +547,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
567 | return error; | 547 | return error; |
568 | 548 | ||
569 | /* Don't create entries in an unlinked directory */ | 549 | /* Don't create entries in an unlinked directory */ |
570 | if (!dip->i_di.di_nlink) | 550 | if (!dip->i_inode.i_nlink) |
571 | return -EPERM; | 551 | return -EPERM; |
572 | 552 | ||
573 | error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL); | 553 | error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL); |
@@ -583,7 +563,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
583 | 563 | ||
584 | if (dip->i_di.di_entries == (u32)-1) | 564 | if (dip->i_di.di_entries == (u32)-1) |
585 | return -EFBIG; | 565 | return -EFBIG; |
586 | if (S_ISDIR(mode) && dip->i_di.di_nlink == (u32)-1) | 566 | if (S_ISDIR(mode) && dip->i_inode.i_nlink == (u32)-1) |
587 | return -EMLINK; | 567 | return -EMLINK; |
588 | 568 | ||
589 | return 0; | 569 | return 0; |
@@ -593,24 +573,24 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode, | |||
593 | unsigned int *uid, unsigned int *gid) | 573 | unsigned int *uid, unsigned int *gid) |
594 | { | 574 | { |
595 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && | 575 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && |
596 | (dip->i_di.di_mode & S_ISUID) && dip->i_di.di_uid) { | 576 | (dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) { |
597 | if (S_ISDIR(*mode)) | 577 | if (S_ISDIR(*mode)) |
598 | *mode |= S_ISUID; | 578 | *mode |= S_ISUID; |
599 | else if (dip->i_di.di_uid != current->fsuid) | 579 | else if (dip->i_inode.i_uid != current->fsuid) |
600 | *mode &= ~07111; | 580 | *mode &= ~07111; |
601 | *uid = dip->i_di.di_uid; | 581 | *uid = dip->i_inode.i_uid; |
602 | } else | 582 | } else |
603 | *uid = current->fsuid; | 583 | *uid = current->fsuid; |
604 | 584 | ||
605 | if (dip->i_di.di_mode & S_ISGID) { | 585 | if (dip->i_inode.i_mode & S_ISGID) { |
606 | if (S_ISDIR(*mode)) | 586 | if (S_ISDIR(*mode)) |
607 | *mode |= S_ISGID; | 587 | *mode |= S_ISGID; |
608 | *gid = dip->i_di.di_gid; | 588 | *gid = dip->i_inode.i_gid; |
609 | } else | 589 | } else |
610 | *gid = current->fsgid; | 590 | *gid = current->fsgid; |
611 | } | 591 | } |
612 | 592 | ||
613 | static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum *inum, | 593 | static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum, |
614 | u64 *generation) | 594 | u64 *generation) |
615 | { | 595 | { |
616 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 596 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
@@ -650,9 +630,9 @@ out: | |||
650 | */ | 630 | */ |
651 | 631 | ||
652 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 632 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, |
653 | const struct gfs2_inum *inum, unsigned int mode, | 633 | const struct gfs2_inum_host *inum, unsigned int mode, |
654 | unsigned int uid, unsigned int gid, | 634 | unsigned int uid, unsigned int gid, |
655 | const u64 *generation) | 635 | const u64 *generation, dev_t dev) |
656 | { | 636 | { |
657 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 637 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
658 | struct gfs2_dinode *di; | 638 | struct gfs2_dinode *di; |
@@ -669,14 +649,15 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
669 | di->di_mode = cpu_to_be32(mode); | 649 | di->di_mode = cpu_to_be32(mode); |
670 | di->di_uid = cpu_to_be32(uid); | 650 | di->di_uid = cpu_to_be32(uid); |
671 | di->di_gid = cpu_to_be32(gid); | 651 | di->di_gid = cpu_to_be32(gid); |
672 | di->di_nlink = cpu_to_be32(0); | 652 | di->di_nlink = 0; |
673 | di->di_size = cpu_to_be64(0); | 653 | di->di_size = 0; |
674 | di->di_blocks = cpu_to_be64(1); | 654 | di->di_blocks = cpu_to_be64(1); |
675 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds()); | 655 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds()); |
676 | di->di_major = di->di_minor = cpu_to_be32(0); | 656 | di->di_major = cpu_to_be32(MAJOR(dev)); |
657 | di->di_minor = cpu_to_be32(MINOR(dev)); | ||
677 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); | 658 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); |
678 | di->di_generation = cpu_to_be64(*generation); | 659 | di->di_generation = cpu_to_be64(*generation); |
679 | di->di_flags = cpu_to_be32(0); | 660 | di->di_flags = 0; |
680 | 661 | ||
681 | if (S_ISREG(mode)) { | 662 | if (S_ISREG(mode)) { |
682 | if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) || | 663 | if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) || |
@@ -693,22 +674,22 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
693 | } | 674 | } |
694 | 675 | ||
695 | di->__pad1 = 0; | 676 | di->__pad1 = 0; |
696 | di->di_payload_format = cpu_to_be32(0); | 677 | di->di_payload_format = cpu_to_be32(S_ISDIR(mode) ? GFS2_FORMAT_DE : 0); |
697 | di->di_height = cpu_to_be32(0); | 678 | di->di_height = 0; |
698 | di->__pad2 = 0; | 679 | di->__pad2 = 0; |
699 | di->__pad3 = 0; | 680 | di->__pad3 = 0; |
700 | di->di_depth = cpu_to_be16(0); | 681 | di->di_depth = 0; |
701 | di->di_entries = cpu_to_be32(0); | 682 | di->di_entries = 0; |
702 | memset(&di->__pad4, 0, sizeof(di->__pad4)); | 683 | memset(&di->__pad4, 0, sizeof(di->__pad4)); |
703 | di->di_eattr = cpu_to_be64(0); | 684 | di->di_eattr = 0; |
704 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); | 685 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); |
705 | 686 | ||
706 | brelse(dibh); | 687 | brelse(dibh); |
707 | } | 688 | } |
708 | 689 | ||
709 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 690 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, |
710 | unsigned int mode, const struct gfs2_inum *inum, | 691 | unsigned int mode, const struct gfs2_inum_host *inum, |
711 | const u64 *generation) | 692 | const u64 *generation, dev_t dev) |
712 | { | 693 | { |
713 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 694 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
714 | unsigned int uid, gid; | 695 | unsigned int uid, gid; |
@@ -729,7 +710,7 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
729 | if (error) | 710 | if (error) |
730 | goto out_quota; | 711 | goto out_quota; |
731 | 712 | ||
732 | init_dinode(dip, gl, inum, mode, uid, gid, generation); | 713 | init_dinode(dip, gl, inum, mode, uid, gid, generation, dev); |
733 | gfs2_quota_change(dip, +1, uid, gid); | 714 | gfs2_quota_change(dip, +1, uid, gid); |
734 | gfs2_trans_end(sdp); | 715 | gfs2_trans_end(sdp); |
735 | 716 | ||
@@ -759,8 +740,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
759 | if (alloc_required < 0) | 740 | if (alloc_required < 0) |
760 | goto fail; | 741 | goto fail; |
761 | if (alloc_required) { | 742 | if (alloc_required) { |
762 | error = gfs2_quota_check(dip, dip->i_di.di_uid, | 743 | error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); |
763 | dip->i_di.di_gid); | ||
764 | if (error) | 744 | if (error) |
765 | goto fail_quota_locks; | 745 | goto fail_quota_locks; |
766 | 746 | ||
@@ -782,16 +762,16 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
782 | goto fail_quota_locks; | 762 | goto fail_quota_locks; |
783 | } | 763 | } |
784 | 764 | ||
785 | error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_di.di_mode)); | 765 | error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_inode.i_mode)); |
786 | if (error) | 766 | if (error) |
787 | goto fail_end_trans; | 767 | goto fail_end_trans; |
788 | 768 | ||
789 | error = gfs2_meta_inode_buffer(ip, &dibh); | 769 | error = gfs2_meta_inode_buffer(ip, &dibh); |
790 | if (error) | 770 | if (error) |
791 | goto fail_end_trans; | 771 | goto fail_end_trans; |
792 | ip->i_di.di_nlink = 1; | 772 | ip->i_inode.i_nlink = 1; |
793 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 773 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
794 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 774 | gfs2_dinode_out(ip, dibh->b_data); |
795 | brelse(dibh); | 775 | brelse(dibh); |
796 | return 0; | 776 | return 0; |
797 | 777 | ||
@@ -860,13 +840,13 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
860 | */ | 840 | */ |
861 | 841 | ||
862 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | 842 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, |
863 | unsigned int mode) | 843 | unsigned int mode, dev_t dev) |
864 | { | 844 | { |
865 | struct inode *inode; | 845 | struct inode *inode; |
866 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; | 846 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; |
867 | struct inode *dir = &dip->i_inode; | 847 | struct inode *dir = &dip->i_inode; |
868 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 848 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
869 | struct gfs2_inum inum; | 849 | struct gfs2_inum_host inum; |
870 | int error; | 850 | int error; |
871 | u64 generation; | 851 | u64 generation; |
872 | 852 | ||
@@ -890,35 +870,12 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
890 | if (error) | 870 | if (error) |
891 | goto fail_gunlock; | 871 | goto fail_gunlock; |
892 | 872 | ||
893 | if (inum.no_addr < dip->i_num.no_addr) { | 873 | error = gfs2_glock_nq_num(sdp, inum.no_addr, &gfs2_inode_glops, |
894 | gfs2_glock_dq(ghs); | 874 | LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); |
895 | 875 | if (error) | |
896 | error = gfs2_glock_nq_num(sdp, inum.no_addr, | 876 | goto fail_gunlock; |
897 | &gfs2_inode_glops, LM_ST_EXCLUSIVE, | ||
898 | GL_SKIP, ghs + 1); | ||
899 | if (error) { | ||
900 | return ERR_PTR(error); | ||
901 | } | ||
902 | |||
903 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs); | ||
904 | error = gfs2_glock_nq(ghs); | ||
905 | if (error) { | ||
906 | gfs2_glock_dq_uninit(ghs + 1); | ||
907 | return ERR_PTR(error); | ||
908 | } | ||
909 | |||
910 | error = create_ok(dip, name, mode); | ||
911 | if (error) | ||
912 | goto fail_gunlock2; | ||
913 | } else { | ||
914 | error = gfs2_glock_nq_num(sdp, inum.no_addr, | ||
915 | &gfs2_inode_glops, LM_ST_EXCLUSIVE, | ||
916 | GL_SKIP, ghs + 1); | ||
917 | if (error) | ||
918 | goto fail_gunlock; | ||
919 | } | ||
920 | 877 | ||
921 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation); | 878 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev); |
922 | if (error) | 879 | if (error) |
923 | goto fail_gunlock2; | 880 | goto fail_gunlock2; |
924 | 881 | ||
@@ -975,7 +932,7 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
975 | 932 | ||
976 | if (ip->i_di.di_entries != 2) { | 933 | if (ip->i_di.di_entries != 2) { |
977 | if (gfs2_consist_inode(ip)) | 934 | if (gfs2_consist_inode(ip)) |
978 | gfs2_dinode_print(&ip->i_di); | 935 | gfs2_dinode_print(ip); |
979 | return -EIO; | 936 | return -EIO; |
980 | } | 937 | } |
981 | 938 | ||
@@ -997,7 +954,12 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
997 | if (error) | 954 | if (error) |
998 | return error; | 955 | return error; |
999 | 956 | ||
1000 | error = gfs2_change_nlink(ip, -2); | 957 | /* It looks odd, but it really should be done twice */ |
958 | error = gfs2_change_nlink(ip, -1); | ||
959 | if (error) | ||
960 | return error; | ||
961 | |||
962 | error = gfs2_change_nlink(ip, -1); | ||
1001 | if (error) | 963 | if (error) |
1002 | return error; | 964 | return error; |
1003 | 965 | ||
@@ -1018,16 +980,16 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
1018 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | 980 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, |
1019 | struct gfs2_inode *ip) | 981 | struct gfs2_inode *ip) |
1020 | { | 982 | { |
1021 | struct gfs2_inum inum; | 983 | struct gfs2_inum_host inum; |
1022 | unsigned int type; | 984 | unsigned int type; |
1023 | int error; | 985 | int error; |
1024 | 986 | ||
1025 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | 987 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) |
1026 | return -EPERM; | 988 | return -EPERM; |
1027 | 989 | ||
1028 | if ((dip->i_di.di_mode & S_ISVTX) && | 990 | if ((dip->i_inode.i_mode & S_ISVTX) && |
1029 | dip->i_di.di_uid != current->fsuid && | 991 | dip->i_inode.i_uid != current->fsuid && |
1030 | ip->i_di.di_uid != current->fsuid && !capable(CAP_FOWNER)) | 992 | ip->i_inode.i_uid != current->fsuid && !capable(CAP_FOWNER)) |
1031 | return -EPERM; | 993 | return -EPERM; |
1032 | 994 | ||
1033 | if (IS_APPEND(&dip->i_inode)) | 995 | if (IS_APPEND(&dip->i_inode)) |
@@ -1044,7 +1006,7 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
1044 | if (!gfs2_inum_equal(&inum, &ip->i_num)) | 1006 | if (!gfs2_inum_equal(&inum, &ip->i_num)) |
1045 | return -ENOENT; | 1007 | return -ENOENT; |
1046 | 1008 | ||
1047 | if (IF2DT(ip->i_di.di_mode) != type) { | 1009 | if (IF2DT(ip->i_inode.i_mode) != type) { |
1048 | gfs2_consist_inode(dip); | 1010 | gfs2_consist_inode(dip); |
1049 | return -EIO; | 1011 | return -EIO; |
1050 | } | 1012 | } |
@@ -1194,7 +1156,7 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1194 | return 0; | 1156 | return 0; |
1195 | 1157 | ||
1196 | curtime = get_seconds(); | 1158 | curtime = get_seconds(); |
1197 | if (curtime - ip->i_di.di_atime >= quantum) { | 1159 | if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { |
1198 | gfs2_glock_dq(gh); | 1160 | gfs2_glock_dq(gh); |
1199 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, | 1161 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, |
1200 | gh); | 1162 | gh); |
@@ -1206,7 +1168,7 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1206 | trying to get exclusive lock. */ | 1168 | trying to get exclusive lock. */ |
1207 | 1169 | ||
1208 | curtime = get_seconds(); | 1170 | curtime = get_seconds(); |
1209 | if (curtime - ip->i_di.di_atime >= quantum) { | 1171 | if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { |
1210 | struct buffer_head *dibh; | 1172 | struct buffer_head *dibh; |
1211 | struct gfs2_dinode *di; | 1173 | struct gfs2_dinode *di; |
1212 | 1174 | ||
@@ -1220,11 +1182,11 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1220 | if (error) | 1182 | if (error) |
1221 | goto fail_end_trans; | 1183 | goto fail_end_trans; |
1222 | 1184 | ||
1223 | ip->i_di.di_atime = curtime; | 1185 | ip->i_inode.i_atime.tv_sec = curtime; |
1224 | 1186 | ||
1225 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1187 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1226 | di = (struct gfs2_dinode *)dibh->b_data; | 1188 | di = (struct gfs2_dinode *)dibh->b_data; |
1227 | di->di_atime = cpu_to_be64(ip->i_di.di_atime); | 1189 | di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); |
1228 | brelse(dibh); | 1190 | brelse(dibh); |
1229 | 1191 | ||
1230 | gfs2_trans_end(sdp); | 1192 | gfs2_trans_end(sdp); |
@@ -1249,92 +1211,6 @@ fail: | |||
1249 | return error; | 1211 | return error; |
1250 | } | 1212 | } |
1251 | 1213 | ||
1252 | /** | ||
1253 | * glock_compare_atime - Compare two struct gfs2_glock structures for sort | ||
1254 | * @arg_a: the first structure | ||
1255 | * @arg_b: the second structure | ||
1256 | * | ||
1257 | * Returns: 1 if A > B | ||
1258 | * -1 if A < B | ||
1259 | * 0 if A == B | ||
1260 | */ | ||
1261 | |||
1262 | static int glock_compare_atime(const void *arg_a, const void *arg_b) | ||
1263 | { | ||
1264 | const struct gfs2_holder *gh_a = *(const struct gfs2_holder **)arg_a; | ||
1265 | const struct gfs2_holder *gh_b = *(const struct gfs2_holder **)arg_b; | ||
1266 | const struct lm_lockname *a = &gh_a->gh_gl->gl_name; | ||
1267 | const struct lm_lockname *b = &gh_b->gh_gl->gl_name; | ||
1268 | |||
1269 | if (a->ln_number > b->ln_number) | ||
1270 | return 1; | ||
1271 | if (a->ln_number < b->ln_number) | ||
1272 | return -1; | ||
1273 | if (gh_a->gh_state == LM_ST_SHARED && gh_b->gh_state == LM_ST_EXCLUSIVE) | ||
1274 | return 1; | ||
1275 | if (gh_a->gh_state == LM_ST_SHARED && (gh_b->gh_flags & GL_ATIME)) | ||
1276 | return 1; | ||
1277 | |||
1278 | return 0; | ||
1279 | } | ||
1280 | |||
1281 | /** | ||
1282 | * gfs2_glock_nq_m_atime - acquire multiple glocks where one may need an | ||
1283 | * atime update | ||
1284 | * @num_gh: the number of structures | ||
1285 | * @ghs: an array of struct gfs2_holder structures | ||
1286 | * | ||
1287 | * Returns: 0 on success (all glocks acquired), | ||
1288 | * errno on failure (no glocks acquired) | ||
1289 | */ | ||
1290 | |||
1291 | int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs) | ||
1292 | { | ||
1293 | struct gfs2_holder **p; | ||
1294 | unsigned int x; | ||
1295 | int error = 0; | ||
1296 | |||
1297 | if (!num_gh) | ||
1298 | return 0; | ||
1299 | |||
1300 | if (num_gh == 1) { | ||
1301 | ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); | ||
1302 | if (ghs->gh_flags & GL_ATIME) | ||
1303 | error = gfs2_glock_nq_atime(ghs); | ||
1304 | else | ||
1305 | error = gfs2_glock_nq(ghs); | ||
1306 | return error; | ||
1307 | } | ||
1308 | |||
1309 | p = kcalloc(num_gh, sizeof(struct gfs2_holder *), GFP_KERNEL); | ||
1310 | if (!p) | ||
1311 | return -ENOMEM; | ||
1312 | |||
1313 | for (x = 0; x < num_gh; x++) | ||
1314 | p[x] = &ghs[x]; | ||
1315 | |||
1316 | sort(p, num_gh, sizeof(struct gfs2_holder *), glock_compare_atime,NULL); | ||
1317 | |||
1318 | for (x = 0; x < num_gh; x++) { | ||
1319 | p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); | ||
1320 | |||
1321 | if (p[x]->gh_flags & GL_ATIME) | ||
1322 | error = gfs2_glock_nq_atime(p[x]); | ||
1323 | else | ||
1324 | error = gfs2_glock_nq(p[x]); | ||
1325 | |||
1326 | if (error) { | ||
1327 | while (x--) | ||
1328 | gfs2_glock_dq(p[x]); | ||
1329 | break; | ||
1330 | } | ||
1331 | } | ||
1332 | |||
1333 | kfree(p); | ||
1334 | return error; | ||
1335 | } | ||
1336 | |||
1337 | |||
1338 | static int | 1214 | static int |
1339 | __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | 1215 | __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) |
1340 | { | 1216 | { |
@@ -1345,10 +1221,8 @@ __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | |||
1345 | if (!error) { | 1221 | if (!error) { |
1346 | error = inode_setattr(&ip->i_inode, attr); | 1222 | error = inode_setattr(&ip->i_inode, attr); |
1347 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); | 1223 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); |
1348 | gfs2_inode_attr_out(ip); | ||
1349 | |||
1350 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1224 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1351 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1225 | gfs2_dinode_out(ip, dibh->b_data); |
1352 | brelse(dibh); | 1226 | brelse(dibh); |
1353 | } | 1227 | } |
1354 | return error; | 1228 | return error; |