aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/bmap.c1
-rw-r--r--fs/gfs2/dir.c412
-rw-r--r--fs/gfs2/dir.h15
-rw-r--r--fs/gfs2/incore.h3
-rw-r--r--fs/gfs2/inode.c14
-rw-r--r--fs/gfs2/log.c34
-rw-r--r--fs/gfs2/ops_dentry.c1
-rw-r--r--fs/gfs2/ops_export.c8
-rw-r--r--fs/gfs2/ops_file.c219
-rw-r--r--fs/gfs2/ops_fstype.c4
-rw-r--r--fs/gfs2/ops_inode.c13
-rw-r--r--fs/gfs2/recovery.c2
-rw-r--r--fs/gfs2/super.c1
-rw-r--r--fs/gfs2/util.c5
-rw-r--r--fs/gfs2/util.h2
15 files changed, 416 insertions, 318 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index cd5e4d863ce2..c7723119acb6 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -13,6 +13,7 @@
13#include <linux/completion.h> 13#include <linux/completion.h>
14#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
15#include <linux/gfs2_ondisk.h> 15#include <linux/gfs2_ondisk.h>
16#include <linux/crc32.h>
16#include <asm/semaphore.h> 17#include <asm/semaphore.h>
17 18
18#include "gfs2.h" 19#include "gfs2.h"
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index f31f163da1a1..ba3438553f33 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -60,6 +60,7 @@
60#include <linux/buffer_head.h> 60#include <linux/buffer_head.h>
61#include <linux/sort.h> 61#include <linux/sort.h>
62#include <linux/gfs2_ondisk.h> 62#include <linux/gfs2_ondisk.h>
63#include <linux/crc32.h>
63#include <asm/semaphore.h> 64#include <asm/semaphore.h>
64 65
65#include "gfs2.h" 66#include "gfs2.h"
@@ -344,7 +345,8 @@ fail:
344} 345}
345 346
346typedef int (*gfs2_dscan_t)(const struct gfs2_dirent *dent, 347typedef int (*gfs2_dscan_t)(const struct gfs2_dirent *dent,
347 const struct qstr *name); 348 const struct qstr *name,
349 void *opaque);
348 350
349static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent, 351static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent,
350 const struct qstr *name, int ret) 352 const struct qstr *name, int ret)
@@ -358,13 +360,15 @@ static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent,
358} 360}
359 361
360static int gfs2_dirent_find(const struct gfs2_dirent *dent, 362static int gfs2_dirent_find(const struct gfs2_dirent *dent,
361 const struct qstr *name) 363 const struct qstr *name,
364 void *opaque)
362{ 365{
363 return __gfs2_dirent_find(dent, name, 1); 366 return __gfs2_dirent_find(dent, name, 1);
364} 367}
365 368
366static int gfs2_dirent_prev(const struct gfs2_dirent *dent, 369static int gfs2_dirent_prev(const struct gfs2_dirent *dent,
367 const struct qstr *name) 370 const struct qstr *name,
371 void *opaque)
368{ 372{
369 return __gfs2_dirent_find(dent, name, 2); 373 return __gfs2_dirent_find(dent, name, 2);
370} 374}
@@ -374,7 +378,8 @@ static int gfs2_dirent_prev(const struct gfs2_dirent *dent,
374 * name->len holds size of block. 378 * name->len holds size of block.
375 */ 379 */
376static int gfs2_dirent_last(const struct gfs2_dirent *dent, 380static int gfs2_dirent_last(const struct gfs2_dirent *dent,
377 const struct qstr *name) 381 const struct qstr *name,
382 void *opaque)
378{ 383{
379 const char *start = name->name; 384 const char *start = name->name;
380 const char *end = (const char *)dent + be16_to_cpu(dent->de_rec_len); 385 const char *end = (const char *)dent + be16_to_cpu(dent->de_rec_len);
@@ -384,17 +389,36 @@ static int gfs2_dirent_last(const struct gfs2_dirent *dent,
384} 389}
385 390
386static int gfs2_dirent_find_space(const struct gfs2_dirent *dent, 391static int gfs2_dirent_find_space(const struct gfs2_dirent *dent,
387 const struct qstr *name) 392 const struct qstr *name,
393 void *opaque)
388{ 394{
389 unsigned required = GFS2_DIRENT_SIZE(name->len); 395 unsigned required = GFS2_DIRENT_SIZE(name->len);
390 unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); 396 unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len));
391 unsigned totlen = be16_to_cpu(dent->de_rec_len); 397 unsigned totlen = be16_to_cpu(dent->de_rec_len);
392 398
399 if (!dent->de_inum.no_addr)
400 actual = GFS2_DIRENT_SIZE(0);
393 if ((totlen - actual) >= required) 401 if ((totlen - actual) >= required)
394 return 1; 402 return 1;
395 return 0; 403 return 0;
396} 404}
397 405
406struct dirent_gather {
407 const struct gfs2_dirent **pdent;
408 unsigned offset;
409};
410
411static int gfs2_dirent_gather(const struct gfs2_dirent *dent,
412 const struct qstr *name,
413 void *opaque)
414{
415 struct dirent_gather *g = opaque;
416 if (dent->de_inum.no_addr) {
417 g->pdent[g->offset++] = dent;
418 }
419 return 0;
420}
421
398/* 422/*
399 * Other possible things to check: 423 * Other possible things to check:
400 * - Inode located within filesystem size (and on valid block) 424 * - Inode located within filesystem size (and on valid block)
@@ -431,19 +455,12 @@ error:
431 return -EIO; 455 return -EIO;
432} 456}
433 457
434static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, 458static int gfs2_dirent_offset(const void *buf)
435 void *buf,
436 unsigned int len, gfs2_dscan_t scan,
437 const struct qstr *name)
438{ 459{
439 struct gfs2_meta_header *h = buf; 460 const struct gfs2_meta_header *h = buf;
440 struct gfs2_dirent *dent, *prev; 461 int offset;
441 unsigned offset;
442 unsigned size;
443 int ret = 0;
444 462
445 BUG_ON(buf == NULL); 463 BUG_ON(buf == NULL);
446 BUG_ON(name == NULL);
447 464
448 switch(be16_to_cpu(h->mh_type)) { 465 switch(be16_to_cpu(h->mh_type)) {
449 case GFS2_METATYPE_LF: 466 case GFS2_METATYPE_LF:
@@ -455,14 +472,36 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode,
455 default: 472 default:
456 goto wrong_type; 473 goto wrong_type;
457 } 474 }
475 return offset;
476wrong_type:
477 printk(KERN_WARNING "gfs2_scan_dirent: wrong block type %u\n",
478 be16_to_cpu(h->mh_type));
479 return -1;
480}
458 481
482static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode,
483 void *buf,
484 unsigned int len, gfs2_dscan_t scan,
485 const struct qstr *name,
486 void *opaque)
487{
488 struct gfs2_dirent *dent, *prev;
489 unsigned offset;
490 unsigned size;
491 int ret = 0;
492
493 ret = gfs2_dirent_offset(buf);
494 if (ret < 0)
495 goto consist_inode;
496
497 offset = ret;
459 prev = NULL; 498 prev = NULL;
460 dent = (struct gfs2_dirent *)(buf + offset); 499 dent = (struct gfs2_dirent *)(buf + offset);
461 size = be16_to_cpu(dent->de_rec_len); 500 size = be16_to_cpu(dent->de_rec_len);
462 if (gfs2_check_dirent(dent, offset, size, len, 1)) 501 if (gfs2_check_dirent(dent, offset, size, len, 1))
463 goto consist_inode; 502 goto consist_inode;
464 do { 503 do {
465 ret = scan(dent, name); 504 ret = scan(dent, name, opaque);
466 if (ret) 505 if (ret)
467 break; 506 break;
468 offset += size; 507 offset += size;
@@ -487,9 +526,6 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode,
487 return ERR_PTR(ret); 526 return ERR_PTR(ret);
488 } 527 }
489 528
490wrong_type:
491 printk(KERN_WARNING "gfs2_scan_dirent: %p wrong block type %u\n", scan,
492 be16_to_cpu(h->mh_type));
493consist_inode: 529consist_inode:
494 gfs2_consist_inode(inode->u.generic_ip); 530 gfs2_consist_inode(inode->u.generic_ip);
495 return ERR_PTR(-EIO); 531 return ERR_PTR(-EIO);
@@ -651,7 +687,8 @@ static struct gfs2_dirent *gfs2_dirent_alloc(struct inode *inode,
651 const struct qstr *name) 687 const struct qstr *name)
652{ 688{
653 struct gfs2_dirent *dent; 689 struct gfs2_dirent *dent;
654 dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, gfs2_dirent_find_space, name); 690 dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size,
691 gfs2_dirent_find_space, name, NULL);
655 if (!dent || IS_ERR(dent)) 692 if (!dent || IS_ERR(dent))
656 return dent; 693 return dent;
657 return gfs2_init_dirent(inode, dent, name, bh); 694 return gfs2_init_dirent(inode, dent, name, bh);
@@ -734,7 +771,7 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
734 return ERR_PTR(error); 771 return ERR_PTR(error);
735 do { 772 do {
736 dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, 773 dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size,
737 scan, name); 774 scan, name, NULL);
738 if (dent) 775 if (dent)
739 goto got_dent; 776 goto got_dent;
740 leaf = (struct gfs2_leaf *)bh->b_data; 777 leaf = (struct gfs2_leaf *)bh->b_data;
@@ -751,7 +788,7 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
751 error = gfs2_meta_inode_buffer(ip, &bh); 788 error = gfs2_meta_inode_buffer(ip, &bh);
752 if (error) 789 if (error)
753 return ERR_PTR(error); 790 return ERR_PTR(error);
754 dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, scan, name); 791 dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, scan, name, NULL);
755got_dent: 792got_dent:
756 *pbh = bh; 793 *pbh = bh;
757 return dent; 794 return dent;
@@ -764,6 +801,7 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh,
764 struct buffer_head *bh = gfs2_meta_new(ip->i_gl, bn); 801 struct buffer_head *bh = gfs2_meta_new(ip->i_gl, bn);
765 struct gfs2_leaf *leaf; 802 struct gfs2_leaf *leaf;
766 struct gfs2_dirent *dent; 803 struct gfs2_dirent *dent;
804 struct qstr name = { .name = "", .len = 0, .hash = 0 };
767 if (!bh) 805 if (!bh)
768 return NULL; 806 return NULL;
769 gfs2_trans_add_bh(ip->i_gl, bh, 1); 807 gfs2_trans_add_bh(ip->i_gl, bh, 1);
@@ -775,12 +813,7 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh,
775 leaf->lf_next = cpu_to_be64(0); 813 leaf->lf_next = cpu_to_be64(0);
776 memset(leaf->lf_reserved, 0, sizeof(leaf->lf_reserved)); 814 memset(leaf->lf_reserved, 0, sizeof(leaf->lf_reserved));
777 dent = (struct gfs2_dirent *)(leaf+1); 815 dent = (struct gfs2_dirent *)(leaf+1);
778 dent->de_inum.no_formal_ino = cpu_to_be64(0); 816 gfs2_qstr2dirent(&name, bh->b_size - sizeof(struct gfs2_leaf), dent);
779 dent->de_inum.no_addr = cpu_to_be64(0);
780 dent->de_hash = cpu_to_be32(0);
781 dent->de_rec_len = cpu_to_be16(bh->b_size - sizeof(struct gfs2_leaf));
782 dent->de_name_len = cpu_to_be16(0);
783 dent->de_type = cpu_to_be16(0);
784 *pbh = bh; 817 *pbh = bh;
785 return leaf; 818 return leaf;
786} 819}
@@ -831,7 +864,7 @@ static int dir_make_exhash(struct inode *inode)
831 sizeof(struct gfs2_leaf); 864 sizeof(struct gfs2_leaf);
832 args.name = bh->b_data; 865 args.name = bh->b_data;
833 dent = gfs2_dirent_scan(dip->i_vnode, bh->b_data, bh->b_size, 866 dent = gfs2_dirent_scan(dip->i_vnode, bh->b_data, bh->b_size,
834 gfs2_dirent_last, &args); 867 gfs2_dirent_last, &args, NULL);
835 if (!dent) { 868 if (!dent) {
836 brelse(bh); 869 brelse(bh);
837 brelse(dibh); 870 brelse(dibh);
@@ -939,7 +972,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
939 lp[x] = cpu_to_be64(bn); 972 lp[x] = cpu_to_be64(bn);
940 973
941 error = gfs2_dir_write_data(dip, (char *)lp, start * sizeof(uint64_t), 974 error = gfs2_dir_write_data(dip, (char *)lp, start * sizeof(uint64_t),
942 half_len * sizeof(uint64_t)); 975 half_len * sizeof(uint64_t));
943 if (error != half_len * sizeof(uint64_t)) { 976 if (error != half_len * sizeof(uint64_t)) {
944 if (error >= 0) 977 if (error >= 0)
945 error = -EIO; 978 error = -EIO;
@@ -965,7 +998,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
965 str.name = (char*)(dent+1); 998 str.name = (char*)(dent+1);
966 str.len = be16_to_cpu(dent->de_name_len); 999 str.len = be16_to_cpu(dent->de_name_len);
967 str.hash = be32_to_cpu(dent->de_hash); 1000 str.hash = be32_to_cpu(dent->de_hash);
968 new = gfs2_dirent_alloc(dip->i_vnode, nbh, &str); 1001 new = gfs2_dirent_alloc(inode, nbh, &str);
969 if (IS_ERR(new)) { 1002 if (IS_ERR(new)) {
970 error = PTR_ERR(new); 1003 error = PTR_ERR(new);
971 break; 1004 break;
@@ -1154,10 +1187,10 @@ static int compare_dents(const void *a, const void *b)
1154 1187
1155static int do_filldir_main(struct gfs2_inode *dip, uint64_t *offset, 1188static int do_filldir_main(struct gfs2_inode *dip, uint64_t *offset,
1156 void *opaque, gfs2_filldir_t filldir, 1189 void *opaque, gfs2_filldir_t filldir,
1157 struct gfs2_dirent **darr, uint32_t entries, 1190 const struct gfs2_dirent **darr, uint32_t entries,
1158 int *copied) 1191 int *copied)
1159{ 1192{
1160 struct gfs2_dirent *dent, *dent_next; 1193 const struct gfs2_dirent *dent, *dent_next;
1161 struct gfs2_inum inum; 1194 struct gfs2_inum inum;
1162 uint64_t off, off_next; 1195 uint64_t off, off_next;
1163 unsigned int x, y; 1196 unsigned int x, y;
@@ -1216,189 +1249,74 @@ static int do_filldir_main(struct gfs2_inode *dip, uint64_t *offset,
1216 return 0; 1249 return 0;
1217} 1250}
1218 1251
1219/** 1252static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
1220 * do_filldir_single - Read directory entries out of a single block 1253 gfs2_filldir_t filldir, int *copied,
1221 * @dip: The GFS2 inode 1254 unsigned *depth, u64 leaf_no)
1222 * @offset: The offset in the file to read from
1223 * @opaque: opaque data to pass to filldir
1224 * @filldir: The function to pass entries to
1225 * @bh: the block
1226 * @entries: the number of entries in the block
1227 * @copied: pointer to int that's non-zero if a entry has been copied out
1228 *
1229 * Returns: errno, >0 on exception from filldir
1230 */
1231
1232static int do_filldir_single(struct gfs2_inode *dip, uint64_t *offset,
1233 void *opaque, gfs2_filldir_t filldir,
1234 struct buffer_head *bh, uint32_t entries,
1235 int *copied)
1236{ 1255{
1237 struct gfs2_dirent **darr; 1256 struct gfs2_inode *ip = inode->u.generic_ip;
1238 struct gfs2_dirent *de; 1257 struct buffer_head *bh;
1239 unsigned int e = 0; 1258 struct gfs2_leaf *lf;
1240 int error; 1259 unsigned entries = 0;
1241 1260 unsigned leaves = 0;
1242 if (!entries) 1261 const struct gfs2_dirent **darr, *dent;
1243 return 0; 1262 struct dirent_gather g;
1244 1263 struct buffer_head **larr;
1245 darr = kcalloc(entries, sizeof(struct gfs2_dirent *), GFP_KERNEL); 1264 int leaf = 0;
1246 if (!darr) 1265 int error, i;
1247 return -ENOMEM; 1266 u64 lfn = leaf_no;
1248 1267
1249 dirent_first(dip, bh, &de);
1250 do { 1268 do {
1251 if (!de->de_inum.no_addr) 1269 error = get_leaf(ip, lfn, &bh);
1252 continue;
1253 if (e >= entries) {
1254 gfs2_consist_inode(dip);
1255 error = -EIO;
1256 goto out;
1257 }
1258 darr[e++] = de;
1259 } while (dirent_next(dip, bh, &de) == 0);
1260
1261 if (e != entries) {
1262 gfs2_consist_inode(dip);
1263 error = -EIO;
1264 goto out;
1265 }
1266
1267 error = do_filldir_main(dip, offset, opaque, filldir, darr,
1268 entries, copied);
1269
1270 out:
1271 kfree(darr);
1272
1273 return error;
1274}
1275
1276/**
1277 * do_filldir_multi - Read directory entries out of a linked leaf list
1278 * @dip: The GFS2 inode
1279 * @offset: The offset in the file to read from
1280 * @opaque: opaque data to pass to filldir
1281 * @filldir: The function to pass entries to
1282 * @bh: the first leaf in the list
1283 * @copied: pointer to int that's non-zero if a entry has been copied out
1284 *
1285 * Returns: errno, >0 on exception from filldir
1286 */
1287
1288static int do_filldir_multi(struct gfs2_inode *dip, uint64_t *offset,
1289 void *opaque, gfs2_filldir_t filldir,
1290 struct buffer_head *bh, int *copied)
1291{
1292 struct buffer_head **larr = NULL;
1293 struct gfs2_dirent **darr;
1294 struct gfs2_leaf *leaf;
1295 struct buffer_head *tmp_bh;
1296 struct gfs2_dirent *de;
1297 unsigned int entries, e = 0;
1298 unsigned int leaves = 0, l = 0;
1299 unsigned int x;
1300 uint64_t ln;
1301 int error = 0;
1302
1303 /* Count leaves and entries */
1304
1305 leaf = (struct gfs2_leaf *)bh->b_data;
1306 entries = be16_to_cpu(leaf->lf_entries);
1307 ln = be64_to_cpu(leaf->lf_next);
1308
1309 while (ln) {
1310 error = get_leaf(dip, ln, &tmp_bh);
1311 if (error) 1270 if (error)
1312 return error; 1271 goto out;
1313 1272 lf = (struct gfs2_leaf *)bh->b_data;
1314 leaf = (struct gfs2_leaf *)tmp_bh->b_data; 1273 if (leaves == 0)
1315 if (leaf->lf_entries) { 1274 *depth = be16_to_cpu(lf->lf_depth);
1316 entries += be16_to_cpu(leaf->lf_entries); 1275 entries += be16_to_cpu(lf->lf_entries);
1317 leaves++; 1276 leaves++;
1318 } 1277 lfn = be64_to_cpu(lf->lf_next);
1319 ln = be64_to_cpu(leaf->lf_next); 1278 brelse(bh);
1320 1279 } while(lfn);
1321 brelse(tmp_bh);
1322 }
1323 1280
1324 if (!entries) 1281 if (!entries)
1325 return 0; 1282 return 0;
1326 1283
1327 if (leaves) { 1284 error = -ENOMEM;
1328 larr = kcalloc(leaves, sizeof(struct buffer_head *),GFP_KERNEL); 1285 larr = kmalloc((leaves + entries) * sizeof(void*), GFP_KERNEL);
1329 if (!larr) 1286 if (!larr)
1330 return -ENOMEM; 1287 goto out;
1331 } 1288 darr = (const struct gfs2_dirent **)(larr + leaves);
1332 1289 g.pdent = darr;
1333 darr = kcalloc(entries, sizeof(struct gfs2_dirent *), GFP_KERNEL); 1290 g.offset = 0;
1334 if (!darr) { 1291 lfn = leaf_no;
1335 kfree(larr);
1336 return -ENOMEM;
1337 }
1338
1339 leaf = (struct gfs2_leaf *)bh->b_data;
1340 if (leaf->lf_entries) {
1341 dirent_first(dip, bh, &de);
1342 do {
1343 if (!de->de_inum.no_addr)
1344 continue;
1345 if (e >= entries) {
1346 gfs2_consist_inode(dip);
1347 error = -EIO;
1348 goto out;
1349 }
1350 darr[e++] = de;
1351 } while (dirent_next(dip, bh, &de) == 0);
1352 }
1353 ln = be64_to_cpu(leaf->lf_next);
1354 1292
1355 while (ln) { 1293 do {
1356 error = get_leaf(dip, ln, &tmp_bh); 1294 error = get_leaf(ip, lfn, &bh);
1357 if (error) 1295 if (error)
1358 goto out; 1296 goto out_kfree;
1359 1297 lf = (struct gfs2_leaf *)bh->b_data;
1360 leaf = (struct gfs2_leaf *)tmp_bh->b_data; 1298 lfn = be64_to_cpu(lf->lf_next);
1361 if (leaf->lf_entries) { 1299 if (lf->lf_entries) {
1362 dirent_first(dip, tmp_bh, &de); 1300 dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size,
1363 do { 1301 gfs2_dirent_gather, NULL, &g);
1364 if (!de->de_inum.no_addr) 1302 error = PTR_ERR(dent);
1365 continue; 1303 if (IS_ERR(dent)) {
1366 if (e >= entries) { 1304 goto out_kfree;
1367 gfs2_consist_inode(dip); 1305 }
1368 error = -EIO; 1306 error = 0;
1369 goto out; 1307 larr[leaf++] = bh;
1370 }
1371 darr[e++] = de;
1372 } while (dirent_next(dip, tmp_bh, &de) == 0);
1373
1374 larr[l++] = tmp_bh;
1375
1376 ln = be64_to_cpu(leaf->lf_next);
1377 } else { 1308 } else {
1378 ln = be64_to_cpu(leaf->lf_next); 1309 brelse(bh);
1379 brelse(tmp_bh);
1380 } 1310 }
1381 } 1311 } while(lfn);
1382 1312
1383 if (gfs2_assert_withdraw(dip->i_sbd, l == leaves)) { 1313 error = do_filldir_main(ip, offset, opaque, filldir, darr,
1384 error = -EIO;
1385 goto out;
1386 }
1387 if (e != entries) {
1388 gfs2_consist_inode(dip);
1389 error = -EIO;
1390 goto out;
1391 }
1392
1393 error = do_filldir_main(dip, offset, opaque, filldir, darr,
1394 entries, copied); 1314 entries, copied);
1395 1315out_kfree:
1396 out: 1316 for(i = 0; i < leaf; i++)
1397 kfree(darr); 1317 brelse(larr[i]);
1398 for (x = 0; x < l; x++)
1399 brelse(larr[x]);
1400 kfree(larr); 1318 kfree(larr);
1401 1319out:
1402 return error; 1320 return error;
1403} 1321}
1404 1322
@@ -1412,18 +1330,18 @@ static int do_filldir_multi(struct gfs2_inode *dip, uint64_t *offset,
1412 * Returns: errno 1330 * Returns: errno
1413 */ 1331 */
1414 1332
1415static int dir_e_read(struct gfs2_inode *dip, uint64_t *offset, void *opaque, 1333static int dir_e_read(struct inode *inode, uint64_t *offset, void *opaque,
1416 gfs2_filldir_t filldir) 1334 gfs2_filldir_t filldir)
1417{ 1335{
1336 struct gfs2_inode *dip = inode->u.generic_ip;
1418 struct gfs2_sbd *sdp = dip->i_sbd; 1337 struct gfs2_sbd *sdp = dip->i_sbd;
1419 struct buffer_head *bh; 1338 uint32_t hsize, len = 0;
1420 struct gfs2_leaf *leaf;
1421 uint32_t hsize, len;
1422 uint32_t ht_offset, lp_offset, ht_offset_cur = -1; 1339 uint32_t ht_offset, lp_offset, ht_offset_cur = -1;
1423 uint32_t hash, index; 1340 uint32_t hash, index;
1424 uint64_t *lp; 1341 uint64_t *lp;
1425 int copied = 0; 1342 int copied = 0;
1426 int error = 0; 1343 int error = 0;
1344 unsigned depth;
1427 1345
1428 hsize = 1 << dip->i_di.di_depth; 1346 hsize = 1 << dip->i_di.di_depth;
1429 if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { 1347 if (hsize * sizeof(uint64_t) != dip->i_di.di_size) {
@@ -1454,61 +1372,66 @@ static int dir_e_read(struct gfs2_inode *dip, uint64_t *offset, void *opaque,
1454 ht_offset_cur = ht_offset; 1372 ht_offset_cur = ht_offset;
1455 } 1373 }
1456 1374
1457 error = get_leaf(dip, be64_to_cpu(lp[lp_offset]), &bh); 1375 error = gfs2_dir_read_leaf(inode, offset, opaque, filldir,
1376 &copied, &depth,
1377 be64_to_cpu(lp[lp_offset]));
1458 if (error) 1378 if (error)
1459 goto out; 1379 break;
1460
1461 leaf = (struct gfs2_leaf *)bh->b_data;
1462 if (leaf->lf_next)
1463 error = do_filldir_multi(dip, offset, opaque, filldir,
1464 bh, &copied);
1465 else
1466 error = do_filldir_single(dip, offset, opaque, filldir,
1467 bh,
1468 be16_to_cpu(leaf->lf_entries),
1469 &copied);
1470
1471 brelse(bh);
1472
1473 if (error) {
1474 if (error > 0)
1475 error = 0;
1476 goto out;
1477 }
1478 1380
1479 len = 1 << (dip->i_di.di_depth - be16_to_cpu(leaf->lf_depth)); 1381 len = 1 << (dip->i_di.di_depth - depth);
1480 index = (index & ~(len - 1)) + len; 1382 index = (index & ~(len - 1)) + len;
1481 } 1383 }
1482 1384
1483 out: 1385out:
1484 kfree(lp); 1386 kfree(lp);
1485 1387 if (error > 0)
1388 error = 0;
1486 return error; 1389 return error;
1487} 1390}
1488 1391
1489static int dir_l_read(struct gfs2_inode *dip, uint64_t *offset, void *opaque, 1392int gfs2_dir_read(struct inode *inode, uint64_t *offset, void *opaque,
1490 gfs2_filldir_t filldir) 1393 gfs2_filldir_t filldir)
1491{ 1394{
1395 struct gfs2_inode *dip = inode->u.generic_ip;
1396 struct dirent_gather g;
1397 const struct gfs2_dirent **darr, *dent;
1492 struct buffer_head *dibh; 1398 struct buffer_head *dibh;
1493 int copied = 0; 1399 int copied = 0;
1494 int error; 1400 int error;
1495 1401
1402 if (!dip->i_di.di_entries)
1403 return 0;
1404
1405 if (dip->i_di.di_flags & GFS2_DIF_EXHASH)
1406 return dir_e_read(inode, offset, opaque, filldir);
1407
1496 if (!gfs2_is_stuffed(dip)) { 1408 if (!gfs2_is_stuffed(dip)) {
1497 gfs2_consist_inode(dip); 1409 gfs2_consist_inode(dip);
1498 return -EIO; 1410 return -EIO;
1499 } 1411 }
1500 1412
1501 if (!dip->i_di.di_entries)
1502 return 0;
1503
1504 error = gfs2_meta_inode_buffer(dip, &dibh); 1413 error = gfs2_meta_inode_buffer(dip, &dibh);
1505 if (error) 1414 if (error)
1506 return error; 1415 return error;
1507 1416
1508 error = do_filldir_single(dip, offset, 1417 error = -ENOMEM;
1509 opaque, filldir, 1418 darr = kmalloc(dip->i_di.di_entries * sizeof(struct gfs2_dirent *),
1510 dibh, dip->i_di.di_entries, 1419 GFP_KERNEL);
1511 &copied); 1420 if (darr) {
1421 g.pdent = darr;
1422 g.offset = 0;
1423 dent = gfs2_dirent_scan(inode, dibh->b_data, dibh->b_size,
1424 gfs2_dirent_gather, NULL, &g);
1425 if (IS_ERR(dent)) {
1426 error = PTR_ERR(dent);
1427 goto out;
1428 }
1429 error = do_filldir_main(dip, offset, opaque, filldir, darr,
1430 dip->i_di.di_entries, &copied);
1431out:
1432 kfree(darr);
1433 }
1434
1512 if (error > 0) 1435 if (error > 0)
1513 error = 0; 1436 error = 0;
1514 1437
@@ -1694,7 +1617,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
1694 return PTR_ERR(dent); 1617 return PTR_ERR(dent);
1695 } 1618 }
1696 /* If not first in block, adjust pointers accordingly */ 1619 /* If not first in block, adjust pointers accordingly */
1697 if (gfs2_dirent_find(dent, name) == 0) { 1620 if (gfs2_dirent_find(dent, name, NULL) == 0) {
1698 prev = dent; 1621 prev = dent;
1699 dent = (struct gfs2_dirent *)((char *)dent + be16_to_cpu(prev->de_rec_len)); 1622 dent = (struct gfs2_dirent *)((char *)dent + be16_to_cpu(prev->de_rec_len));
1700 } 1623 }
@@ -1724,19 +1647,6 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
1724 return error; 1647 return error;
1725} 1648}
1726 1649
1727int gfs2_dir_read(struct gfs2_inode *dip, uint64_t *offset, void *opaque,
1728 gfs2_filldir_t filldir)
1729{
1730 int error;
1731
1732 if (dip->i_di.di_flags & GFS2_DIF_EXHASH)
1733 error = dir_e_read(dip, offset, opaque, filldir);
1734 else
1735 error = dir_l_read(dip, offset, opaque, filldir);
1736
1737 return error;
1738}
1739
1740/** 1650/**
1741 * gfs2_dir_mvino - Change inode number of directory entry 1651 * gfs2_dir_mvino - Change inode number of directory entry
1742 * @dip: The GFS2 inode 1652 * @dip: The GFS2 inode
diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h
index 8fd4dc0f700e..42b3a1f34deb 100644
--- a/fs/gfs2/dir.h
+++ b/fs/gfs2/dir.h
@@ -32,7 +32,7 @@ int gfs2_dir_search(struct inode *dir, const struct qstr *filename,
32int gfs2_dir_add(struct inode *inode, const struct qstr *filename, 32int gfs2_dir_add(struct inode *inode, const struct qstr *filename,
33 const struct gfs2_inum *inum, unsigned int type); 33 const struct gfs2_inum *inum, unsigned int type);
34int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename); 34int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename);
35int gfs2_dir_read(struct gfs2_inode *dip, uint64_t * offset, void *opaque, 35int gfs2_dir_read(struct inode *inode, uint64_t * offset, void *opaque,
36 gfs2_filldir_t filldir); 36 gfs2_filldir_t filldir);
37int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, 37int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
38 struct gfs2_inum *new_inum, unsigned int new_type); 38 struct gfs2_inum *new_inum, unsigned int new_type);
@@ -44,6 +44,19 @@ int gfs2_diradd_alloc_required(struct inode *dir,
44int gfs2_dir_get_buffer(struct gfs2_inode *ip, uint64_t block, int new, 44int gfs2_dir_get_buffer(struct gfs2_inode *ip, uint64_t block, int new,
45 struct buffer_head **bhp); 45 struct buffer_head **bhp);
46 46
47static inline uint32_t gfs2_disk_hash(const char *data, int len)
48{
49 return crc32_le(0xFFFFFFFF, data, len) ^ 0xFFFFFFFF;
50}
51
52
53static inline void gfs2_str2qstr(struct qstr *name, const char *fname)
54{
55 name->name = fname;
56 name->len = strlen(fname);
57 name->hash = gfs2_disk_hash(name->name, name->len);
58}
59
47/* N.B. This probably ought to take inum & type as args as well */ 60/* N.B. This probably ought to take inum & type as args as well */
48static inline void gfs2_qstr2dirent(const struct qstr *name, u16 reclen, struct gfs2_dirent *dent) 61static inline void gfs2_qstr2dirent(const struct qstr *name, u16 reclen, struct gfs2_dirent *dent)
49{ 62{
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 62f109e553c4..be307185f492 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -634,8 +634,7 @@ struct gfs2_sbd {
634 struct list_head sd_log_le_databuf; 634 struct list_head sd_log_le_databuf;
635 635
636 unsigned int sd_log_blks_free; 636 unsigned int sd_log_blks_free;
637 struct list_head sd_log_blks_list; 637 struct mutex sd_log_reserve_mutex;
638 wait_queue_head_t sd_log_blks_wait;
639 638
640 uint64_t sd_log_sequence; 639 uint64_t sd_log_sequence;
641 unsigned int sd_log_head; 640 unsigned int sd_log_head;
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index d403d51d5b0f..6140c2434e85 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -15,6 +15,7 @@
15#include <linux/posix_acl.h> 15#include <linux/posix_acl.h>
16#include <linux/sort.h> 16#include <linux/sort.h>
17#include <linux/gfs2_ondisk.h> 17#include <linux/gfs2_ondisk.h>
18#include <linux/crc32.h>
18#include <asm/semaphore.h> 19#include <asm/semaphore.h>
19 20
20#include "gfs2.h" 21#include "gfs2.h"
@@ -701,9 +702,7 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
701struct inode *gfs2_lookup_simple(struct inode *dip, const char *name) 702struct inode *gfs2_lookup_simple(struct inode *dip, const char *name)
702{ 703{
703 struct qstr qstr; 704 struct qstr qstr;
704 qstr.name = name; 705 gfs2_str2qstr(&qstr, name);
705 qstr.len = strlen(name);
706 qstr.hash = gfs2_disk_hash(qstr.name, qstr.len);
707 return gfs2_lookupi(dip, &qstr, 1, NULL); 706 return gfs2_lookupi(dip, &qstr, 1, NULL);
708} 707}
709 708
@@ -1389,9 +1388,7 @@ int gfs2_rmdiri(struct gfs2_inode *dip, struct qstr *name,
1389 if (error) 1388 if (error)
1390 return error; 1389 return error;
1391 1390
1392 dotname.len = 1; 1391 gfs2_str2qstr(&dotname, ".");
1393 dotname.name = ".";
1394 dotname.hash = gfs2_disk_hash(dotname.name, dotname.len);
1395 error = gfs2_dir_del(ip, &dotname); 1392 error = gfs2_dir_del(ip, &dotname);
1396 if (error) 1393 if (error)
1397 return error; 1394 return error;
@@ -1487,10 +1484,7 @@ int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
1487 struct qstr dotdot; 1484 struct qstr dotdot;
1488 int error = 0; 1485 int error = 0;
1489 1486
1490 memset(&dotdot, 0, sizeof(struct qstr)); 1487 gfs2_str2qstr(&dotdot, "..");
1491 dotdot.name = "..";
1492 dotdot.len = 2;
1493 dotdot.hash = gfs2_disk_hash(dotdot.name, dotdot.len);
1494 1488
1495 igrab(dir); 1489 igrab(dir);
1496 1490
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index e6a84f7a9b71..16c14441a371 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -13,6 +13,7 @@
13#include <linux/completion.h> 13#include <linux/completion.h>
14#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
15#include <linux/gfs2_ondisk.h> 15#include <linux/gfs2_ondisk.h>
16#include <linux/crc32.h>
16#include <asm/semaphore.h> 17#include <asm/semaphore.h>
17 18
18#include "gfs2.h" 19#include "gfs2.h"
@@ -24,18 +25,13 @@
24#include "lops.h" 25#include "lops.h"
25#include "meta_io.h" 26#include "meta_io.h"
26#include "util.h" 27#include "util.h"
28#include "dir.h"
27 29
28#define PULL 1 30#define PULL 1
29 31
30static void do_lock_wait(struct gfs2_sbd *sdp, wait_queue_head_t *wq,
31 atomic_t *a)
32{
33 wait_event(*wq, atomic_read(a) ? 0 : 1);
34}
35
36static void lock_for_trans(struct gfs2_sbd *sdp) 32static void lock_for_trans(struct gfs2_sbd *sdp)
37{ 33{
38 do_lock_wait(sdp, &sdp->sd_log_trans_wq, &sdp->sd_log_flush_count); 34 wait_event(sdp->sd_log_trans_wq, atomic_read(&sdp->sd_log_flush_count) ? 0 : 1);
39 atomic_inc(&sdp->sd_log_trans_count); 35 atomic_inc(&sdp->sd_log_trans_count);
40} 36}
41 37
@@ -49,7 +45,7 @@ static void unlock_from_trans(struct gfs2_sbd *sdp)
49static void gfs2_lock_for_flush(struct gfs2_sbd *sdp) 45static void gfs2_lock_for_flush(struct gfs2_sbd *sdp)
50{ 46{
51 atomic_inc(&sdp->sd_log_flush_count); 47 atomic_inc(&sdp->sd_log_flush_count);
52 do_lock_wait(sdp, &sdp->sd_log_flush_wq, &sdp->sd_log_trans_count); 48 wait_event(sdp->sd_log_flush_wq, atomic_read(&sdp->sd_log_trans_count) ? 0 : 1);
53} 49}
54 50
55static void gfs2_unlock_from_flush(struct gfs2_sbd *sdp) 51static void gfs2_unlock_from_flush(struct gfs2_sbd *sdp)
@@ -191,37 +187,19 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail)
191 187
192int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) 188int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
193{ 189{
194 LIST_HEAD(list);
195 unsigned int try = 0; 190 unsigned int try = 0;
196 191
197 if (gfs2_assert_warn(sdp, blks) || 192 if (gfs2_assert_warn(sdp, blks) ||
198 gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks)) 193 gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks))
199 return -EINVAL; 194 return -EINVAL;
200 195
196 mutex_lock(&sdp->sd_log_reserve_mutex);
201 for (;;) { 197 for (;;) {
202 gfs2_log_lock(sdp); 198 gfs2_log_lock(sdp);
203 if (list_empty(&list)) {
204 list_add_tail(&list, &sdp->sd_log_blks_list);
205 while (sdp->sd_log_blks_list.next != &list) {
206 DECLARE_WAITQUEUE(__wait_chan, current);
207 set_current_state(TASK_UNINTERRUPTIBLE);
208 add_wait_queue(&sdp->sd_log_blks_wait,
209 &__wait_chan);
210 gfs2_log_unlock(sdp);
211 schedule();
212 gfs2_log_lock(sdp);
213 remove_wait_queue(&sdp->sd_log_blks_wait,
214 &__wait_chan);
215 set_current_state(TASK_RUNNING);
216 }
217 }
218 /* Never give away the last block so we can
219 always pull the tail if we need to. */
220 if (sdp->sd_log_blks_free > blks) { 199 if (sdp->sd_log_blks_free > blks) {
221 sdp->sd_log_blks_free -= blks; 200 sdp->sd_log_blks_free -= blks;
222 list_del(&list);
223 gfs2_log_unlock(sdp); 201 gfs2_log_unlock(sdp);
224 wake_up(&sdp->sd_log_blks_wait); 202 mutex_unlock(&sdp->sd_log_reserve_mutex);
225 break; 203 break;
226 } 204 }
227 205
diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c
index b54608f9df50..958371076093 100644
--- a/fs/gfs2/ops_dentry.c
+++ b/fs/gfs2/ops_dentry.c
@@ -14,6 +14,7 @@
14#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
15#include <linux/smp_lock.h> 15#include <linux/smp_lock.h>
16#include <linux/gfs2_ondisk.h> 16#include <linux/gfs2_ondisk.h>
17#include <linux/crc32.h>
17#include <asm/semaphore.h> 18#include <asm/semaphore.h>
18 19
19#include "gfs2.h" 20#include "gfs2.h"
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
index b27bce74a795..be16c68263d1 100644
--- a/fs/gfs2/ops_export.c
+++ b/fs/gfs2/ops_export.c
@@ -13,6 +13,7 @@
13#include <linux/completion.h> 13#include <linux/completion.h>
14#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
15#include <linux/gfs2_ondisk.h> 15#include <linux/gfs2_ondisk.h>
16#include <linux/crc32.h>
16#include <asm/semaphore.h> 17#include <asm/semaphore.h>
17 18
18#include "gfs2.h" 19#include "gfs2.h"
@@ -153,7 +154,7 @@ static int gfs2_get_name(struct dentry *parent, char *name,
153 if (error) 154 if (error)
154 return error; 155 return error;
155 156
156 error = gfs2_dir_read(dip, &offset, &gnfd, get_name_filldir); 157 error = gfs2_dir_read(dir, &offset, &gnfd, get_name_filldir);
157 158
158 gfs2_glock_dq_uninit(&gh); 159 gfs2_glock_dq_uninit(&gh);
159 160
@@ -165,12 +166,11 @@ static int gfs2_get_name(struct dentry *parent, char *name,
165 166
166static struct dentry *gfs2_get_parent(struct dentry *child) 167static struct dentry *gfs2_get_parent(struct dentry *child)
167{ 168{
168 struct qstr dotdot = { .name = "..", .len = 2 }; 169 struct qstr dotdot;
169 struct inode *inode; 170 struct inode *inode;
170 struct dentry *dentry; 171 struct dentry *dentry;
171 172
172 dotdot.hash = gfs2_disk_hash(dotdot.name, dotdot.len); 173 gfs2_str2qstr(&dotdot, "..");
173
174 inode = gfs2_lookupi(child->d_inode, &dotdot, 1, NULL); 174 inode = gfs2_lookupi(child->d_inode, &dotdot, 1, NULL);
175 175
176 if (!inode) 176 if (!inode)
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 6333a14cf77a..ac8e1238cb6f 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -19,6 +19,8 @@
19#include <linux/smp_lock.h> 19#include <linux/smp_lock.h>
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include <linux/gfs2_ondisk.h> 21#include <linux/gfs2_ondisk.h>
22#include <linux/ext2_fs.h>
23#include <linux/crc32.h>
22#include <asm/semaphore.h> 24#include <asm/semaphore.h>
23#include <asm/uaccess.h> 25#include <asm/uaccess.h>
24 26
@@ -39,6 +41,7 @@
39#include "rgrp.h" 41#include "rgrp.h"
40#include "trans.h" 42#include "trans.h"
41#include "util.h" 43#include "util.h"
44#include "eaops.h"
42 45
43/* "bad" is for NFS support */ 46/* "bad" is for NFS support */
44struct filldir_bad_entry { 47struct filldir_bad_entry {
@@ -357,7 +360,8 @@ static int filldir_reg_func(void *opaque, const char *name, unsigned int length,
357 360
358static int readdir_reg(struct file *file, void *dirent, filldir_t filldir) 361static int readdir_reg(struct file *file, void *dirent, filldir_t filldir)
359{ 362{
360 struct gfs2_inode *dip = file->f_mapping->host->u.generic_ip; 363 struct inode *dir = file->f_mapping->host;
364 struct gfs2_inode *dip = dir->u.generic_ip;
361 struct filldir_reg fdr; 365 struct filldir_reg fdr;
362 struct gfs2_holder d_gh; 366 struct gfs2_holder d_gh;
363 uint64_t offset = file->f_pos; 367 uint64_t offset = file->f_pos;
@@ -375,7 +379,7 @@ static int readdir_reg(struct file *file, void *dirent, filldir_t filldir)
375 return error; 379 return error;
376 } 380 }
377 381
378 error = gfs2_dir_read(dip, &offset, &fdr, filldir_reg_func); 382 error = gfs2_dir_read(dir, &offset, &fdr, filldir_reg_func);
379 383
380 gfs2_glock_dq_uninit(&d_gh); 384 gfs2_glock_dq_uninit(&d_gh);
381 385
@@ -446,7 +450,8 @@ static int filldir_bad_func(void *opaque, const char *name, unsigned int length,
446 450
447static int readdir_bad(struct file *file, void *dirent, filldir_t filldir) 451static int readdir_bad(struct file *file, void *dirent, filldir_t filldir)
448{ 452{
449 struct gfs2_inode *dip = file->f_mapping->host->u.generic_ip; 453 struct inode *dir = file->f_mapping->host;
454 struct gfs2_inode *dip = dir->u.generic_ip;
450 struct gfs2_sbd *sdp = dip->i_sbd; 455 struct gfs2_sbd *sdp = dip->i_sbd;
451 struct filldir_reg fdr; 456 struct filldir_reg fdr;
452 unsigned int entries, size; 457 unsigned int entries, size;
@@ -479,7 +484,7 @@ static int readdir_bad(struct file *file, void *dirent, filldir_t filldir)
479 goto out; 484 goto out;
480 } 485 }
481 486
482 error = gfs2_dir_read(dip, &offset, fdb, filldir_bad_func); 487 error = gfs2_dir_read(dir, &offset, fdb, filldir_bad_func);
483 488
484 gfs2_glock_dq_uninit(&d_gh); 489 gfs2_glock_dq_uninit(&d_gh);
485 490
@@ -531,6 +536,210 @@ static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir)
531 return error; 536 return error;
532} 537}
533 538
539const struct gfs2_flag_eattr {
540 u32 flag;
541 u32 ext2;
542} gfs2_flag_eattrs[] = {
543 {
544 .flag = GFS2_DIF_IMMUTABLE,
545 .ext2 = EXT2_IMMUTABLE_FL,
546 }, {
547 .flag = GFS2_DIF_APPENDONLY,
548 .ext2 = EXT2_APPEND_FL,
549 }, {
550 .flag = GFS2_DIF_JDATA,
551 .ext2 = EXT2_JOURNAL_DATA_FL,
552 }, {
553 .flag = GFS2_DIF_EXHASH,
554 .ext2 = EXT2_INDEX_FL,
555 }, {
556 .flag = GFS2_DIF_EA_INDIRECT,
557 }, {
558 .flag = GFS2_DIF_DIRECTIO,
559 }, {
560 .flag = GFS2_DIF_NOATIME,
561 .ext2 = EXT2_NOATIME_FL,
562 }, {
563 .flag = GFS2_DIF_SYNC,
564 .ext2 = EXT2_SYNC_FL,
565 }, {
566 .flag = GFS2_DIF_SYSTEM,
567 }, {
568 .flag = GFS2_DIF_TRUNC_IN_PROG,
569 }, {
570 .flag = GFS2_DIF_INHERIT_JDATA,
571 }, {
572 .flag = GFS2_DIF_INHERIT_DIRECTIO,
573 }, {
574 },
575};
576
577static const struct gfs2_flag_eattr *get_by_ext2(u32 ext2)
578{
579 const struct gfs2_flag_eattr *p = gfs2_flag_eattrs;
580 for(; p->flag; p++) {
581 if (ext2 == p->ext2)
582 return p;
583 }
584 return NULL;
585}
586
587static const struct gfs2_flag_eattr *get_by_gfs2(u32 gfs2)
588{
589 const struct gfs2_flag_eattr *p = gfs2_flag_eattrs;
590 for(; p->flag; p++) {
591 if (gfs2 == p->flag)
592 return p;
593 }
594 return NULL;
595}
596
597static u32 gfs2_flags_to_ext2(u32 gfs2)
598{
599 const struct gfs2_flag_eattr *ea;
600 u32 ext2 = 0;
601 u32 mask = 1;
602
603 for(; mask != 0; mask <<=1) {
604 if (mask & gfs2) {
605 ea = get_by_gfs2(mask);
606 if (ea)
607 ext2 |= ea->ext2;
608 }
609 }
610 return ext2;
611}
612
613static int gfs2_flags_from_ext2(u32 *gfs2, u32 ext2)
614{
615 const struct gfs2_flag_eattr *ea;
616 u32 mask = 1;
617
618 for(; mask != 0; mask <<= 1) {
619 if (mask & ext2) {
620 ea = get_by_ext2(mask);
621 if (ea == NULL)
622 return -EINVAL;
623 *gfs2 |= ea->flag;
624 }
625 }
626 return 0;
627}
628
629static int get_ext2_flags(struct inode *inode, u32 __user *ptr)
630{
631 struct gfs2_inode *ip = inode->u.generic_ip;
632 struct gfs2_holder gh;
633 int error;
634 u32 ext2;
635
636 gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh);
637 error = gfs2_glock_nq_m_atime(1, &gh);
638 if (error)
639 return error;
640
641 ext2 = gfs2_flags_to_ext2(ip->i_di.di_flags);
642 if (put_user(ext2, ptr))
643 error = -EFAULT;
644
645 gfs2_glock_dq_m(1, &gh);
646 gfs2_holder_uninit(&gh);
647 return error;
648}
649
650/* Flags that can be set by user space */
651#define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA| \
652 GFS2_DIF_DIRECTIO| \
653 GFS2_DIF_IMMUTABLE| \
654 GFS2_DIF_APPENDONLY| \
655 GFS2_DIF_NOATIME| \
656 GFS2_DIF_SYNC| \
657 GFS2_DIF_SYSTEM| \
658 GFS2_DIF_INHERIT_DIRECTIO| \
659 GFS2_DIF_INHERIT_JDATA)
660
661/**
662 * gfs2_set_flags - set flags on an inode
663 * @inode: The inode
664 * @flags: The flags to set
665 * @mask: Indicates which flags are valid
666 *
667 */
668static int gfs2_set_flags(struct inode *inode, u32 flags, u32 mask)
669{
670 struct gfs2_inode *ip = inode->u.generic_ip;
671 struct buffer_head *bh;
672 struct gfs2_holder gh;
673 int error;
674 u32 new_flags;
675
676 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
677 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
678 if (error)
679 return error;
680
681 new_flags = (ip->i_di.di_flags & ~mask) | (flags & mask);
682 if ((new_flags ^ flags) == 0)
683 goto out;
684
685 error = -EINVAL;
686 if ((new_flags ^ flags) & ~GFS2_FLAGS_USER_SET)
687 goto out;
688
689 if (S_ISDIR(inode->i_mode)) {
690 if ((new_flags ^ flags) & (GFS2_DIF_JDATA | GFS2_DIF_DIRECTIO))
691 goto out;
692 } else if (S_ISREG(inode->i_mode)) {
693 if ((new_flags ^ flags) & (GFS2_DIF_INHERIT_DIRECTIO|
694 GFS2_DIF_INHERIT_JDATA))
695 goto out;
696 } else
697 goto out;
698
699 error = -EPERM;
700 if (IS_IMMUTABLE(inode) && (new_flags & GFS2_DIF_IMMUTABLE))
701 goto out;
702 if (IS_APPEND(inode) && (new_flags & GFS2_DIF_APPENDONLY))
703 goto out;
704 error = gfs2_repermission(inode, MAY_WRITE, NULL);
705 if (error)
706 goto out;
707
708 error = gfs2_meta_inode_buffer(ip, &bh);
709 if (error)
710 goto out;
711 gfs2_trans_add_bh(ip->i_gl, bh, 1);
712 ip->i_di.di_flags = new_flags;
713 gfs2_dinode_out(&ip->i_di, bh->b_data);
714 brelse(bh);
715out:
716 gfs2_glock_dq_uninit(&gh);
717 return error;
718}
719
720static int set_ext2_flags(struct inode *inode, u32 __user *ptr)
721{
722 u32 ext2, gfs2;
723 if (get_user(ext2, ptr))
724 return -EFAULT;
725 if (gfs2_flags_from_ext2(&gfs2, ext2))
726 return -EINVAL;
727 return gfs2_set_flags(inode, gfs2, ~0);
728}
729
730int gfs2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
731 unsigned long arg)
732{
733 switch(cmd) {
734 case EXT2_IOC_GETFLAGS:
735 return get_ext2_flags(inode, (u32 __user *)arg);
736 case EXT2_IOC_SETFLAGS:
737 return set_ext2_flags(inode, (u32 __user *)arg);
738 }
739 return -ENOTTY;
740}
741
742
534/** 743/**
535 * gfs2_mmap - 744 * gfs2_mmap -
536 * @file: The file to map 745 * @file: The file to map
@@ -832,6 +1041,7 @@ struct file_operations gfs2_file_fops = {
832 .write = generic_file_write, 1041 .write = generic_file_write,
833 .writev = generic_file_writev, 1042 .writev = generic_file_writev,
834 .aio_write = generic_file_aio_write, 1043 .aio_write = generic_file_aio_write,
1044 .ioctl = gfs2_ioctl,
835 .mmap = gfs2_mmap, 1045 .mmap = gfs2_mmap,
836 .open = gfs2_open, 1046 .open = gfs2_open,
837 .release = gfs2_close, 1047 .release = gfs2_close,
@@ -843,6 +1053,7 @@ struct file_operations gfs2_file_fops = {
843 1053
844struct file_operations gfs2_dir_fops = { 1054struct file_operations gfs2_dir_fops = {
845 .readdir = gfs2_readdir, 1055 .readdir = gfs2_readdir,
1056 .ioctl = gfs2_ioctl,
846 .open = gfs2_open, 1057 .open = gfs2_open,
847 .release = gfs2_close, 1058 .release = gfs2_close,
848 .fsync = gfs2_fsync, 1059 .fsync = gfs2_fsync,
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 8d2c557b3ff4..2628bf326334 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -97,9 +97,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
97 INIT_LIST_HEAD(&sdp->sd_log_le_rg); 97 INIT_LIST_HEAD(&sdp->sd_log_le_rg);
98 INIT_LIST_HEAD(&sdp->sd_log_le_databuf); 98 INIT_LIST_HEAD(&sdp->sd_log_le_databuf);
99 99
100 INIT_LIST_HEAD(&sdp->sd_log_blks_list); 100 mutex_init(&sdp->sd_log_reserve_mutex);
101 init_waitqueue_head(&sdp->sd_log_blks_wait);
102
103 INIT_LIST_HEAD(&sdp->sd_ail1_list); 101 INIT_LIST_HEAD(&sdp->sd_ail1_list);
104 INIT_LIST_HEAD(&sdp->sd_ail2_list); 102 INIT_LIST_HEAD(&sdp->sd_ail2_list);
105 103
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index e8ab9d254b76..1e2b709711ae 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -18,6 +18,7 @@
18#include <linux/xattr.h> 18#include <linux/xattr.h>
19#include <linux/posix_acl.h> 19#include <linux/posix_acl.h>
20#include <linux/gfs2_ondisk.h> 20#include <linux/gfs2_ondisk.h>
21#include <linux/crc32.h>
21#include <asm/semaphore.h> 22#include <asm/semaphore.h>
22#include <asm/uaccess.h> 23#include <asm/uaccess.h>
23 24
@@ -417,18 +418,16 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
417 if (!gfs2_assert_withdraw(sdp, !error)) { 418 if (!gfs2_assert_withdraw(sdp, !error)) {
418 struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data; 419 struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data;
419 struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1); 420 struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1);
420 struct qstr str = { .name = ".", .len = 1 }; 421 struct qstr str;
421 str.hash = gfs2_disk_hash(str.name, str.len);
422 422
423 gfs2_str2qstr(&str, ".");
423 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 424 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
424 gfs2_qstr2dirent(&str, GFS2_DIRENT_SIZE(str.len), dent); 425 gfs2_qstr2dirent(&str, GFS2_DIRENT_SIZE(str.len), dent);
425 dent->de_inum = di->di_num; /* already GFS2 endian */ 426 dent->de_inum = di->di_num; /* already GFS2 endian */
426 dent->de_type = DT_DIR; 427 dent->de_type = DT_DIR;
427 di->di_entries = cpu_to_be32(1); 428 di->di_entries = cpu_to_be32(1);
428 429
429 str.name = ".."; 430 gfs2_str2qstr(&str, "..");
430 str.len = 2;
431 str.hash = gfs2_disk_hash(str.name, str.len);
432 dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1)); 431 dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1));
433 gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent); 432 gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent);
434 433
@@ -772,9 +771,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
772 771
773 if (dir_rename) { 772 if (dir_rename) {
774 struct qstr name; 773 struct qstr name;
775 name.len = 2; 774 gfs2_str2qstr(&name, "..");
776 name.name = "..";
777 name.hash = gfs2_disk_hash(name.name, name.len);
778 775
779 error = gfs2_change_nlink(ndip, +1); 776 error = gfs2_change_nlink(ndip, +1);
780 if (error) 777 if (error)
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c
index 2df450e2f433..6c7e2e880e32 100644
--- a/fs/gfs2/recovery.c
+++ b/fs/gfs2/recovery.c
@@ -13,6 +13,7 @@
13#include <linux/completion.h> 13#include <linux/completion.h>
14#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
15#include <linux/gfs2_ondisk.h> 15#include <linux/gfs2_ondisk.h>
16#include <linux/crc32.h>
16#include <asm/semaphore.h> 17#include <asm/semaphore.h>
17 18
18#include "gfs2.h" 19#include "gfs2.h"
@@ -27,6 +28,7 @@
27#include "recovery.h" 28#include "recovery.h"
28#include "super.h" 29#include "super.h"
29#include "util.h" 30#include "util.h"
31#include "dir.h"
30 32
31int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk, 33int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk,
32 struct buffer_head **bh) 34 struct buffer_head **bh)
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 71cca7629403..a4da649d086f 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -12,6 +12,7 @@
12#include <linux/spinlock.h> 12#include <linux/spinlock.h>
13#include <linux/completion.h> 13#include <linux/completion.h>
14#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
15#include <linux/crc32.h>
15#include <linux/gfs2_ondisk.h> 16#include <linux/gfs2_ondisk.h>
16#include <asm/semaphore.h> 17#include <asm/semaphore.h>
17 18
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index 8b22fa91bd14..7cd9e25639c4 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
@@ -28,11 +28,6 @@ kmem_cache_t *gfs2_glock_cachep __read_mostly;
28kmem_cache_t *gfs2_inode_cachep __read_mostly; 28kmem_cache_t *gfs2_inode_cachep __read_mostly;
29kmem_cache_t *gfs2_bufdata_cachep __read_mostly; 29kmem_cache_t *gfs2_bufdata_cachep __read_mostly;
30 30
31uint32_t gfs2_disk_hash(const char *data, int len)
32{
33 return crc32_le(0xFFFFFFFF, data, len) ^ 0xFFFFFFFF;
34}
35
36void gfs2_assert_i(struct gfs2_sbd *sdp) 31void gfs2_assert_i(struct gfs2_sbd *sdp)
37{ 32{
38 printk(KERN_EMERG "GFS2: fsid=%s: fatal assertion failed\n", 33 printk(KERN_EMERG "GFS2: fsid=%s: fatal assertion failed\n",
diff --git a/fs/gfs2/util.h b/fs/gfs2/util.h
index 8d6eba3bdf0a..addbe304993e 100644
--- a/fs/gfs2/util.h
+++ b/fs/gfs2/util.h
@@ -10,8 +10,6 @@
10#ifndef __UTIL_DOT_H__ 10#ifndef __UTIL_DOT_H__
11#define __UTIL_DOT_H__ 11#define __UTIL_DOT_H__
12 12
13uint32_t gfs2_disk_hash(const char *data, int len);
14
15 13
16#define fs_printk(level, fs, fmt, arg...) \ 14#define fs_printk(level, fs, fmt, arg...) \
17 printk(level "GFS2: fsid=%s: " fmt , (fs)->sd_fsname , ## arg) 15 printk(level "GFS2: fsid=%s: " fmt , (fs)->sd_fsname , ## arg)