inode.c (27e6c7a3ce29ae5fa5bec4ed5917f8508bfac120) inode.c (622daaff0a8975fb5c5b95f24f3234550ba32e92)
1/*
2 * inode.c - NILFS inode operations.
3 *
4 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or

--- 902 unchanged lines hidden (view full) ---

911 if (mdi) {
912 nilfs_mdt_mark_dirty(inode);
913 return;
914 }
915 nilfs_transaction_begin(inode->i_sb, &ti, 0);
916 nilfs_mark_inode_dirty(inode);
917 nilfs_transaction_commit(inode->i_sb); /* never fails */
918}
1/*
2 * inode.c - NILFS inode operations.
3 *
4 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or

--- 902 unchanged lines hidden (view full) ---

911 if (mdi) {
912 nilfs_mdt_mark_dirty(inode);
913 return;
914 }
915 nilfs_transaction_begin(inode->i_sb, &ti, 0);
916 nilfs_mark_inode_dirty(inode);
917 nilfs_transaction_commit(inode->i_sb); /* never fails */
918}
919
920int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
921 __u64 start, __u64 len)
922{
923 struct the_nilfs *nilfs = NILFS_I_NILFS(inode);
924 __u64 logical = 0, phys = 0, size = 0;
925 __u32 flags = 0;
926 loff_t isize;
927 sector_t blkoff, end_blkoff;
928 sector_t delalloc_blkoff;
929 unsigned long delalloc_blklen;
930 unsigned int blkbits = inode->i_blkbits;
931 int ret, n;
932
933 ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC);
934 if (ret)
935 return ret;
936
937 mutex_lock(&inode->i_mutex);
938
939 isize = i_size_read(inode);
940
941 blkoff = start >> blkbits;
942 end_blkoff = (start + len - 1) >> blkbits;
943
944 delalloc_blklen = nilfs_find_uncommitted_extent(inode, blkoff,
945 &delalloc_blkoff);
946
947 do {
948 __u64 blkphy;
949 unsigned int maxblocks;
950
951 if (delalloc_blklen && blkoff == delalloc_blkoff) {
952 if (size) {
953 /* End of the current extent */
954 ret = fiemap_fill_next_extent(
955 fieinfo, logical, phys, size, flags);
956 if (ret)
957 break;
958 }
959 if (blkoff > end_blkoff)
960 break;
961
962 flags = FIEMAP_EXTENT_MERGED | FIEMAP_EXTENT_DELALLOC;
963 logical = blkoff << blkbits;
964 phys = 0;
965 size = delalloc_blklen << blkbits;
966
967 blkoff = delalloc_blkoff + delalloc_blklen;
968 delalloc_blklen = nilfs_find_uncommitted_extent(
969 inode, blkoff, &delalloc_blkoff);
970 continue;
971 }
972
973 /*
974 * Limit the number of blocks that we look up so as
975 * not to get into the next delayed allocation extent.
976 */
977 maxblocks = INT_MAX;
978 if (delalloc_blklen)
979 maxblocks = min_t(sector_t, delalloc_blkoff - blkoff,
980 maxblocks);
981 blkphy = 0;
982
983 down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
984 n = nilfs_bmap_lookup_contig(
985 NILFS_I(inode)->i_bmap, blkoff, &blkphy, maxblocks);
986 up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
987
988 if (n < 0) {
989 int past_eof;
990
991 if (unlikely(n != -ENOENT))
992 break; /* error */
993
994 /* HOLE */
995 blkoff++;
996 past_eof = ((blkoff << blkbits) >= isize);
997
998 if (size) {
999 /* End of the current extent */
1000
1001 if (past_eof)
1002 flags |= FIEMAP_EXTENT_LAST;
1003
1004 ret = fiemap_fill_next_extent(
1005 fieinfo, logical, phys, size, flags);
1006 if (ret)
1007 break;
1008 size = 0;
1009 }
1010 if (blkoff > end_blkoff || past_eof)
1011 break;
1012 } else {
1013 if (size) {
1014 if (phys && blkphy << blkbits == phys + size) {
1015 /* The current extent goes on */
1016 size += n << blkbits;
1017 } else {
1018 /* Terminate the current extent */
1019 ret = fiemap_fill_next_extent(
1020 fieinfo, logical, phys, size,
1021 flags);
1022 if (ret || blkoff > end_blkoff)
1023 break;
1024
1025 /* Start another extent */
1026 flags = FIEMAP_EXTENT_MERGED;
1027 logical = blkoff << blkbits;
1028 phys = blkphy << blkbits;
1029 size = n << blkbits;
1030 }
1031 } else {
1032 /* Start a new extent */
1033 flags = FIEMAP_EXTENT_MERGED;
1034 logical = blkoff << blkbits;
1035 phys = blkphy << blkbits;
1036 size = n << blkbits;
1037 }
1038 blkoff += n;
1039 }
1040 cond_resched();
1041 } while (true);
1042
1043 /* If ret is 1 then we just hit the end of the extent array */
1044 if (ret == 1)
1045 ret = 0;
1046
1047 mutex_unlock(&inode->i_mutex);
1048 return ret;
1049}