bk://linux-ntfs.bkbits.net/ntfs-2.6-devel aia21@cantab.net|ChangeSet|20040921210957|52376 aia21 # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/09/21 21:05:32-07:00 akpm@bix.(none) # Merge bk://linux-ntfs.bkbits.net/ntfs-2.6-devel # into bix.(none):/usr/src/bk-ntfs # # fs/ntfs/super.c # 2004/09/21 21:05:28-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/inode.c # 2004/09/21 21:05:28-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/dir.c # 2004/09/21 21:05:28-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/attrib.c # 2004/09/21 21:05:27-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/aops.c # 2004/09/21 21:05:27-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/21 22:09:57+01:00 aia21@cantab.net # NTFS: - Fix endianness bug in ntfs_external_attr_find(). # - Change ntfs_{external_,}attr_find() to return 0 on success, -ENOENT # if the attribute is not found, and -EIO on real error. In the case # of -ENOENT, the search context is updated to describe the attribute # before which the attribute being searched for would need to be # inserted if such an action were to be desired and in the case of # ntfs_external_attr_find() the search context is also updated to # indicate the attribute list entry before which the attribute list # entry of the attribute being searched for would need to be inserted # if such an action were to be desired. Also make ntfs_find_attr() # static and remove its prototype from attrib.h as it is not used # anywhere other than attrib.c. Update ntfs_attr_lookup() and all # callers of ntfs_{external,}attr_{find,lookup}() for the new return # values. # - Force use of ntfs_attr_find() in ntfs_attr_lookup() when searching # for the attribute list attribute itself. # # Signed-off-by: Anton Altaparmakov # # fs/ntfs/namei.c # 2004/09/21 21:59:21+01:00 aia21@cantab.net +15 -9 # Update for new ntfs_attr_lookup() return values. # # fs/ntfs/super.c # 2004/09/21 21:57:49+01:00 aia21@cantab.net +4 -5 # Update for new ntfs_attr_lookup() return values. # # fs/ntfs/index.c # 2004/09/21 21:57:39+01:00 aia21@cantab.net +11 -9 # Update for new ntfs_attr_lookup() return values. # # fs/ntfs/inode.c # 2004/09/21 21:56:11+01:00 aia21@cantab.net +97 -43 # Update for new ntfs_attr_lookup() return values. # # fs/ntfs/dir.c # 2004/09/21 21:55:46+01:00 aia21@cantab.net +21 -12 # Update for new ntfs_attr_lookup() return values. # # fs/ntfs/attrib.h # 2004/09/21 21:54:57+01:00 aia21@cantab.net +1 -5 # Update for new ntfs_attr_lookup() prototype. # Remove ntfs_attr_find() prototype as it is now static. # # fs/ntfs/attrib.c # 2004/09/21 21:53:15+01:00 aia21@cantab.net +163 -90 # - Change ntfs_{external_,}attr_find() to return 0 on success, -ENOENT # if the attribute is not found, and -EIO on real error. In the case # of -ENOENT, the search context is updated to describe the attribute # before which the attribute being searched for would need to be # inserted if such an action were to be desired and in the case of # ntfs_external_attr_find() the search context is also updated to # indicate the attribute list entry before which the attribute list # entry of the attribute being searched for would need to be inserted # if such an action were to be desired. Also make ntfs_find_attr() # static and remove its prototype from attrib.h as it is not used # anywhere other than attrib.c. Update ntfs_attr_lookup() and all # callers of ntfs_{external,}attr_{find,lookup}() for the new return # values. # # fs/ntfs/aops.c # 2004/09/21 21:52:34+01:00 aia21@cantab.net +9 -12 # Update for new ntfs_attr_lookup() return values. # # fs/ntfs/ChangeLog # 2004/09/21 21:52:27+01:00 aia21@cantab.net +16 -0 # Update # # ChangeSet # 2004/09/21 12:57:50+01:00 aia21@cantab.net # NTFS: Rename {{re,}init,get,put}_attr_search_ctx() to # ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type # attr_search_context to ntfs_attr_search_ctx. # # Signed-off-by: Anton Altaparmakov # # fs/ntfs/super.c # 2004/09/21 12:57:42+01:00 aia21@cantab.net +9 -9 # Rename {{re,}init,get,put}_attr_search_ctx() to # ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type # attr_search_context to ntfs_attr_search_ctx. # # fs/ntfs/namei.c # 2004/09/21 12:57:41+01:00 aia21@cantab.net +8 -8 # Rename {{re,}init,get,put}_attr_search_ctx() to # ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type # attr_search_context to ntfs_attr_search_ctx. # # fs/ntfs/inode.c # 2004/09/21 12:57:41+01:00 aia21@cantab.net +32 -32 # Rename {{re,}init,get,put}_attr_search_ctx() to # ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type # attr_search_context to ntfs_attr_search_ctx. # # fs/ntfs/index.h # 2004/09/21 12:57:41+01:00 aia21@cantab.net +1 -1 # Rename {{re,}init,get,put}_attr_search_ctx() to # ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type # attr_search_context to ntfs_attr_search_ctx. # # fs/ntfs/index.c # 2004/09/21 12:57:41+01:00 aia21@cantab.net +5 -5 # Rename {{re,}init,get,put}_attr_search_ctx() to # ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type # attr_search_context to ntfs_attr_search_ctx. # # fs/ntfs/dir.c # 2004/09/21 12:57:41+01:00 aia21@cantab.net +15 -15 # Rename {{re,}init,get,put}_attr_search_ctx() to # ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type # attr_search_context to ntfs_attr_search_ctx. # # fs/ntfs/attrib.h # 2004/09/21 12:57:41+01:00 aia21@cantab.net +7 -7 # Rename {{re,}init,get,put}_attr_search_ctx() to # ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type # attr_search_context to ntfs_attr_search_ctx. # # fs/ntfs/attrib.c # 2004/09/21 12:57:41+01:00 aia21@cantab.net +25 -26 # Rename {{re,}init,get,put}_attr_search_ctx() to # ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type # attr_search_context to ntfs_attr_search_ctx. # # fs/ntfs/aops.c # 2004/09/21 12:57:40+01:00 aia21@cantab.net +14 -14 # Rename {{re,}init,get,put}_attr_search_ctx() to # ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type # attr_search_context to ntfs_attr_search_ctx. # # fs/ntfs/ChangeLog # 2004/09/21 12:57:40+01:00 aia21@cantab.net +3 -0 # Update # # ChangeSet # 2004/09/21 12:30:02+01:00 aia21@cantab.net # NTFS: Rename {find,lookup}_attr() to ntfs_attr_{find,lookup}() as well as # find_external_attr() to ntfs_external_attr_find() to cleanup the # namespace a bit and to be more consistent with libntfs. # # Signed-off-by: Anton Altaparmakov # # fs/ntfs/super.c # 2004/09/21 12:29:53+01:00 aia21@cantab.net +4 -3 # Rename {find,lookup}_attr() to ntfs_attr_{find,lookup}() as well as # find_external_attr() to ntfs_external_attr_find() to cleanup the # namespace a bit and to be more consistent with libntfs. # # fs/ntfs/namei.c # 2004/09/21 12:29:53+01:00 aia21@cantab.net +4 -4 # Rename {find,lookup}_attr() to ntfs_attr_{find,lookup}() as well as # find_external_attr() to ntfs_external_attr_find() to cleanup the # namespace a bit and to be more consistent with libntfs. # # fs/ntfs/inode.c # 2004/09/21 12:29:53+01:00 aia21@cantab.net +21 -21 # Rename {find,lookup}_attr() to ntfs_attr_{find,lookup}() as well as # find_external_attr() to ntfs_external_attr_find() to cleanup the # namespace a bit and to be more consistent with libntfs. # # fs/ntfs/index.c # 2004/09/21 12:29:53+01:00 aia21@cantab.net +1 -1 # Rename {find,lookup}_attr() to ntfs_attr_{find,lookup}() as well as # find_external_attr() to ntfs_external_attr_find() to cleanup the # namespace a bit and to be more consistent with libntfs. # # fs/ntfs/dir.c # 2004/09/21 12:29:53+01:00 aia21@cantab.net +6 -6 # Rename {find,lookup}_attr() to ntfs_attr_{find,lookup}() as well as # find_external_attr() to ntfs_external_attr_find() to cleanup the # namespace a bit and to be more consistent with libntfs. # # fs/ntfs/attrib.h # 2004/09/21 12:29:52+01:00 aia21@cantab.net +3 -3 # Rename {find,lookup}_attr() to ntfs_attr_{find,lookup}() as well as # find_external_attr() to ntfs_external_attr_find() to cleanup the # namespace a bit and to be more consistent with libntfs. # # fs/ntfs/attrib.c # 2004/09/21 12:29:52+01:00 aia21@cantab.net +63 -58 # Rename {find,lookup}_attr() to ntfs_attr_{find,lookup}() as well as # find_external_attr() to ntfs_external_attr_find() to cleanup the # namespace a bit and to be more consistent with libntfs. # # fs/ntfs/aops.c # 2004/09/21 12:29:52+01:00 aia21@cantab.net +4 -4 # Rename {find,lookup}_attr() to ntfs_attr_{find,lookup}() as well as # find_external_attr() to ntfs_external_attr_find() to cleanup the # namespace a bit and to be more consistent with libntfs. # # fs/ntfs/ChangeLog # 2004/09/21 12:29:52+01:00 aia21@cantab.net +7 -0 # Update # # ChangeSet # 2004/09/20 14:19:39-07:00 akpm@bix.(none) # Merge bk://linux-ntfs.bkbits.net/ntfs-2.6-devel # into bix.(none):/usr/src/bk-ntfs # # fs/ntfs/super.c # 2004/09/20 14:19:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/inode.c # 2004/09/20 14:19:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/20 09:24:11+01:00 ntfs@flatcap.org # Merge flatcap.org:/home/flatcap/backup/bk/ntfs-2.6 # into flatcap.org:/home/flatcap/backup/bk/ntfs-2.6-devel # # fs/ntfs/super.c # 2004/09/20 09:24:06+01:00 ntfs@flatcap.org +0 -0 # Auto merged # # fs/ntfs/inode.c # 2004/09/20 09:24:06+01:00 ntfs@flatcap.org +0 -0 # Auto merged # # ChangeSet # 2004/09/17 13:12:24-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-ntfs # # fs/ntfs/super.c # 2004/09/17 13:12:20-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/inode.c # 2004/09/17 13:12:20-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/16 11:33:15+01:00 aia21@cantab.net # NTFS: Fix a potential bug in fs/ntfs/mft.c::map_extent_mft_record() that # could occur in the future for when we start closing/freeing extent # inodes if we don't set base_ni->ext.extent_ntfs_inos to NULL after # we free it. # # Signed-off-by: Anton Altaparmakov # # fs/ntfs/mft.c # 2004/09/16 11:33:06+01:00 aia21@cantab.net +2 -1 # Fix a potential bug that could occur in the future for when we start # closing/freeing extent inodes if we don't set base_ni->ext.extent_ntfs_inos # to NULL after we free it. # # ChangeSet # 2004/09/14 14:26:30-07:00 akpm@bix.(none) # Merge bk://linux-ntfs.bkbits.net/ntfs-2.6-devel # into bix.(none):/usr/src/bk-ntfs # # fs/ntfs/super.c # 2004/09/14 14:26:26-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/inode.c # 2004/09/14 14:26:26-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/14 14:30:26+01:00 aia21@cantab.net # NTFS: Fix scheduling latencies in ntfs_fill_super() by dropping the BKL # because the code itself is using the ntfs_lock semaphore which # provides safe locking. (Ingo Molnar) # # Signed-off-by: Ingo Molnar # Signed-off-by: Anton Altaparmakov # # fs/ntfs/super.c # 2004/09/14 14:30:16+01:00 aia21@cantab.net +5 -0 # Fix scheduling latencies in ntfs_fill_super() by dropping the BKL # because the code itself is using the ntfs_lock semaphore which # provides safe locking. (Ingo Molnar) # # fs/ntfs/ChangeLog # 2004/09/14 14:30:15+01:00 aia21@cantab.net +3 -0 # Update # # fs/ntfs/debug.c # 2004/09/06 10:56:54+01:00 aia21@cantab.net +1 -1 # Add parentheses after function name in ntfs_debug(). # # ChangeSet # 2004/08/31 10:12:45+01:00 aia21@cantab.net # Merge ssh://linux-ntfs@bkbits.net/ntfs-2.6-devel # into cantab.net:/home/src/ntfs-2.6-devel # # fs/ntfs/super.c # 2004/08/31 10:12:42+01:00 aia21@cantab.net +0 -0 # Auto merged # # ChangeSet # 2004/08/27 13:55:53-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-ntfs # # fs/ntfs/super.c # 2004/08/27 13:55:49-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/27 14:14:03+01:00 aia21@cantab.net # NTFS: Remove vol->nr_mft_records as it was pretty meaningless and optimize # the calculation of total/free inodes as used by statfs(). # # Signed-off-by: Anton Altaparmakov # # fs/ntfs/volume.h # 2004/08/27 14:13:55+01:00 aia21@cantab.net +0 -3 # Remove vol->nr_mft_records as it was pretty meaningless and optimize # the calculation of total/free inodes as used by statfs(). # # fs/ntfs/super.c # 2004/08/27 14:13:55+01:00 aia21@cantab.net +12 -9 # Remove vol->nr_mft_records as it was pretty meaningless and optimize # the calculation of total/free inodes as used by statfs(). # # fs/ntfs/inode.c # 2004/08/27 14:13:54+01:00 aia21@cantab.net +2 -6 # Remove vol->nr_mft_records as it was pretty meaningless and optimize # the calculation of total/free inodes as used by statfs(). # # fs/ntfs/Makefile # 2004/08/27 14:13:54+01:00 aia21@cantab.net +1 -1 # Update # # fs/ntfs/ChangeLog # 2004/08/27 14:13:54+01:00 aia21@cantab.net +5 -0 # Update # # ChangeSet # 2004/08/24 17:34:17-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-ntfs # # fs/ntfs/super.c # 2004/08/24 17:34:13-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/23 16:42:55-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-ntfs # # fs/ntfs/inode.c # 2004/08/23 16:42:51-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/dir.c # 2004/08/23 16:42:51-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/attrib.c # 2004/08/23 16:42:51-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/aops.c # 2004/08/23 16:42:51-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/23 14:26:58-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-ntfs # # fs/ntfs/inode.c # 2004/08/23 14:26:52-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/dir.c # 2004/08/23 14:26:52-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/attrib.c # 2004/08/23 14:26:52-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/aops.c # 2004/08/23 14:26:52-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/18 12:24:54-07:00 akpm@bix.(none) # Merge bk://linux-ntfs.bkbits.net/ntfs-2.6-devel # into bix.(none):/usr/src/bk-ntfs # # fs/ntfs/super.c # 2004/08/18 12:24:51-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/16 10:41:28-07:00 akpm@bix.(none) # Merge bk://linux-ntfs.bkbits.net/ntfs-2.6-devel # into bix.(none):/usr/src/bk-ntfs # # fs/ntfs/super.c # 2004/08/16 10:41:24-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/07 14:39:35-07:00 akpm@bix.(none) # Merge bk://linux-ntfs.bkbits.net/ntfs-2.6-devel # into bix.(none):/usr/src/bk-ntfs # # fs/ntfs/super.c # 2004/08/07 14:39:32-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/dir.c # 2004/08/07 14:39:32-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/compress.c # 2004/08/07 14:39:32-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/07/26 23:13:47-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-ntfs # # fs/ntfs/super.c # 2004/07/26 23:13:44-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/dir.c # 2004/07/26 23:13:43-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/ntfs/compress.c # 2004/07/26 23:13:43-07:00 akpm@bix.(none) +0 -0 # Auto merged # diff -Nru a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog --- a/fs/ntfs/ChangeLog 2004-09-21 21:06:35 -07:00 +++ b/fs/ntfs/ChangeLog 2004-09-21 21:06:35 -07:00 @@ -21,6 +21,40 @@ - Enable the code for setting the NT4 compatibility flag when we start making NTFS 1.2 specific modifications. +2.1.18-WIP + + - Remove vol->nr_mft_records as it was pretty meaningless and optimize + the calculation of total/free inodes as used by statfs(). + - Fix scheduling latencies in ntfs_fill_super() by dropping the BKL + because the code itself is using the ntfs_lock semaphore which + provides safe locking. (Ingo Molnar) + - Fix a potential bug in fs/ntfs/mft.c::map_extent_mft_record() that + could occur in the future for when we start closing/freeing extent + inodes if we don't set base_ni->ext.extent_ntfs_inos to NULL after + we free it. + - Rename {find,lookup}_attr() to ntfs_attr_{find,lookup}() as well as + find_external_attr() to ntfs_external_attr_find() to cleanup the + namespace a bit and to be more consistent with libntfs. + - Rename {{re,}init,get,put}_attr_search_ctx() to + ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type + attr_search_context to ntfs_attr_search_ctx. + - Force use of ntfs_attr_find() in ntfs_attr_lookup() when searching + for the attribute list attribute itself. + - Fix endianness bug in ntfs_external_attr_find(). + - Change ntfs_{external_,}attr_find() to return 0 on success, -ENOENT + if the attribute is not found, and -EIO on real error. In the case + of -ENOENT, the search context is updated to describe the attribute + before which the attribute being searched for would need to be + inserted if such an action were to be desired and in the case of + ntfs_external_attr_find() the search context is also updated to + indicate the attribute list entry before which the attribute list + entry of the attribute being searched for would need to be inserted + if such an action were to be desired. Also make ntfs_find_attr() + static and remove its prototype from attrib.h as it is not used + anywhere other than attrib.c. Update ntfs_attr_lookup() and all + callers of ntfs_{external,}attr_{find,lookup}() for the new return + values. + 2.1.17 - Fix bugs in mount time error code paths and other updates. - Implement bitmap modification code (fs/ntfs/bitmap.[hc]). This diff -Nru a/fs/ntfs/Makefile b/fs/ntfs/Makefile --- a/fs/ntfs/Makefile 2004-09-21 21:06:35 -07:00 +++ b/fs/ntfs/Makefile 2004-09-21 21:06:35 -07:00 @@ -6,7 +6,7 @@ index.o inode.o mft.o mst.o namei.o super.o sysctl.o unistr.o \ upcase.o -EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.17\" +EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.18-WIP\" ifeq ($(CONFIG_NTFS_DEBUG),y) EXTRA_CFLAGS += -DDEBUG diff -Nru a/fs/ntfs/aops.c b/fs/ntfs/aops.c --- a/fs/ntfs/aops.c 2004-09-21 21:06:35 -07:00 +++ b/fs/ntfs/aops.c 2004-09-21 21:06:35 -07:00 @@ -348,7 +348,7 @@ s64 attr_pos; ntfs_inode *ni, *base_ni; u8 *kaddr; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; MFT_RECORD *mrec; u32 attr_len; int err = 0; @@ -397,16 +397,15 @@ err = PTR_ERR(mrec); goto err_out; } - ctx = get_attr_search_ctx(base_ni, mrec); + ctx = ntfs_attr_get_search_ctx(base_ni, mrec); if (unlikely(!ctx)) { err = -ENOMEM; goto unm_err_out; } - if (unlikely(!lookup_attr(ni->type, ni->name, ni->name_len, - CASE_SENSITIVE, 0, NULL, 0, ctx))) { - err = -ENOENT; + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, 0, NULL, 0, ctx); + if (unlikely(err)) goto put_unm_err_out; - } /* Starting position of the page within the attribute value. */ attr_pos = page->index << PAGE_CACHE_SHIFT; @@ -433,7 +432,7 @@ SetPageUptodate(page); put_unm_err_out: - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unm_err_out: unmap_mft_record(base_ni); err_out: @@ -1030,7 +1029,7 @@ struct inode *vi; ntfs_inode *ni, *base_ni; char *kaddr; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; MFT_RECORD *m; u32 attr_len, bytes; int err; @@ -1117,16 +1116,15 @@ ctx = NULL; goto err_out; } - ctx = get_attr_search_ctx(base_ni, m); + ctx = ntfs_attr_get_search_ctx(base_ni, m); if (unlikely(!ctx)) { err = -ENOMEM; goto err_out; } - if (unlikely(!lookup_attr(ni->type, ni->name, ni->name_len, - CASE_SENSITIVE, 0, NULL, 0, ctx))) { - err = -ENOENT; + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, 0, NULL, 0, ctx); + if (unlikely(err)) goto err_out; - } /* Starting position of the page within the attribute value. */ attr_pos = page->index << PAGE_CACHE_SHIFT; @@ -1201,7 +1199,7 @@ /* Mark the mft record dirty, so it gets written back. */ mark_mft_record_dirty(ctx->ntfs_ino); - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(base_ni); return 0; err_out: @@ -1221,7 +1219,7 @@ } unlock_page(page); if (ctx) - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); if (m) unmap_mft_record(base_ni); return err; @@ -1683,9 +1681,9 @@ * We thus defer the uptodate bringing of the page region outside the * region written to to ntfs_commit_write(). The reason for doing this * is that we save one round of: - * map_mft_record(), get_attr_search_ctx(), lookup_attr(), - * kmap_atomic(), kunmap_atomic(), put_attr_search_ctx(), - * unmap_mft_record(). + * map_mft_record(), ntfs_attr_get_search_ctx(), + * ntfs_attr_lookup(), kmap_atomic(), kunmap_atomic(), + * ntfs_attr_put_search_ctx(), unmap_mft_record(). * Which is obviously a very worthwhile save. * * Thus we just return success now... @@ -1804,7 +1802,7 @@ struct inode *vi; ntfs_inode *ni, *base_ni; char *kaddr, *kattr; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; MFT_RECORD *m; u32 attr_len, bytes; int err; @@ -1891,16 +1889,15 @@ ctx = NULL; goto err_out; } - ctx = get_attr_search_ctx(base_ni, m); + ctx = ntfs_attr_get_search_ctx(base_ni, m); if (unlikely(!ctx)) { err = -ENOMEM; goto err_out; } - if (unlikely(!lookup_attr(ni->type, ni->name, ni->name_len, - CASE_SENSITIVE, 0, NULL, 0, ctx))) { - err = -ENOENT; + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, 0, NULL, 0, ctx); + if (unlikely(err)) goto err_out; - } /* Starting position of the page within the attribute value. */ attr_pos = page->index << PAGE_CACHE_SHIFT; @@ -1966,7 +1963,7 @@ /* Mark the mft record dirty, so it gets written back. */ mark_mft_record_dirty(ctx->ntfs_ino); - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(base_ni); ntfs_debug("Done."); return 0; @@ -1993,7 +1990,7 @@ SetPageError(page); } if (ctx) - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); if (m) unmap_mft_record(base_ni); return err; diff -Nru a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c --- a/fs/ntfs/attrib.c 2004-09-21 21:06:35 -07:00 +++ b/fs/ntfs/attrib.c 2004-09-21 21:06:35 -07:00 @@ -946,7 +946,7 @@ int ntfs_map_runlist(ntfs_inode *ni, VCN vcn) { ntfs_inode *base_ni; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; MFT_RECORD *mrec; int err = 0; @@ -961,17 +961,15 @@ mrec = map_mft_record(base_ni); if (IS_ERR(mrec)) return PTR_ERR(mrec); - ctx = get_attr_search_ctx(base_ni, mrec); - if (!ctx) { + ctx = ntfs_attr_get_search_ctx(base_ni, mrec); + if (unlikely(!ctx)) { err = -ENOMEM; goto err_out; } - if (!lookup_attr(ni->type, ni->name, ni->name_len, CASE_SENSITIVE, vcn, - NULL, 0, ctx)) { - put_attr_search_ctx(ctx); - err = -ENOENT; - goto err_out; - } + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, vcn, NULL, 0, ctx); + if (unlikely(err)) + goto put_err_out; down_write(&ni->runlist.lock); /* Make sure someone else didn't do the work while we were sleeping. */ @@ -987,7 +985,8 @@ } up_write(&ni->runlist.lock); - put_attr_search_ctx(ctx); +put_err_out: + ntfs_attr_put_search_ctx(ctx); err_out: unmap_mft_record(base_ni); return err; @@ -1148,7 +1147,7 @@ } /** - * find_attr - find (next) attribute in mft record + * ntfs_attr_find - find (next) attribute in mft record * @type: attribute type to find * @name: attribute name to find (optional, i.e. NULL means don't care) * @name_len: attribute name length (only needed if @name present) @@ -1157,47 +1156,56 @@ * @val_len: attribute value length * @ctx: search context with mft record and attribute to search from * - * You shouldn't need to call this function directly. Use lookup_attr() instead. + * You should not need to call this function directly. Use ntfs_attr_lookup() + * instead. + * + * ntfs_attr_find() takes a search context @ctx as parameter and searches the + * mft record specified by @ctx->mrec, beginning at @ctx->attr, for an + * attribute of @type, optionally @name and @val. + * + * If the attribute is found, ntfs_attr_find() returns 0 and @ctx->attr will + * point to the found attribute. + * + * If the attribute is not found, ntfs_attr_find() returns -ENOENT and + * @ctx->attr will point to the attribute before which the attribute being + * searched for would need to be inserted if such an action were to be desired. * - * find_attr() takes a search context @ctx as parameter and searches the mft - * record specified by @ctx->mrec, beginning at @ctx->attr, for an attribute of - * @type, optionally @name and @val. If found, find_attr() returns TRUE and - * @ctx->attr will point to the found attribute. If not found, find_attr() - * returns FALSE and @ctx->attr is undefined (i.e. do not rely on it not - * changing). + * On actual error, ntfs_attr_find() returns -EIO. In this case @ctx->attr is + * undefined and in particular do not rely on it not changing. * - * If @ctx->is_first is TRUE, the search begins with @ctx->attr itself. If it + * If @ctx->is_first is TRUE, the search begins with @ctx->attr itself. If it * is FALSE, the search begins after @ctx->attr. * * If @ic is IGNORE_CASE, the @name comparisson is not case sensitive and * @ctx->ntfs_ino must be set to the ntfs inode to which the mft record - * @ctx->mrec belongs. This is so we can get at the ntfs volume and hence at - * the upcase table. If @ic is CASE_SENSITIVE, the comparison is case - * sensitive. When @name is present, @name_len is the @name length in Unicode + * @ctx->mrec belongs. This is so we can get at the ntfs volume and hence at + * the upcase table. If @ic is CASE_SENSITIVE, the comparison is case + * sensitive. When @name is present, @name_len is the @name length in Unicode * characters. * * If @name is not present (NULL), we assume that the unnamed attribute is * being searched for. * - * Finally, the resident attribute value @val is looked for, if present. If @val - * is not present (NULL), @val_len is ignored. + * Finally, the resident attribute value @val is looked for, if present. If + * @val is not present (NULL), @val_len is ignored. * - * find_attr() only searches the specified mft record and it ignores the + * ntfs_attr_find() only searches the specified mft record and it ignores the * presence of an attribute list attribute (unless it is the one being searched - * for, obviously). If you need to take attribute lists into consideration, use - * lookup_attr() instead (see below). This also means that you cannot use - * find_attr() to search for extent records of non-resident attributes, as - * extents with lowest_vcn != 0 are usually described by the attribute list - * attribute only. - Note that it is possible that the first extent is only in - * the attribute list while the last extent is in the base mft record, so don't - * rely on being able to find the first extent in the base mft record. + * for, obviously). If you need to take attribute lists into consideration, + * use ntfs_attr_lookup() instead (see below). This also means that you cannot + * use ntfs_attr_find() to search for extent records of non-resident + * attributes, as extents with lowest_vcn != 0 are usually described by the + * attribute list attribute only. - Note that it is possible that the first + * extent is only in the attribute list while the last extent is in the base + * mft record, so do not rely on being able to find the first extent in the + * base mft record. * * Warning: Never use @val when looking for attribute types which can be * non-resident as this most likely will result in a crash! */ -BOOL find_attr(const ATTR_TYPES type, const ntfschar *name, const u32 name_len, - const IGNORE_CASE_BOOL ic, const u8 *val, const u32 val_len, - attr_search_context *ctx) +static int ntfs_attr_find(const ATTR_TYPES type, const ntfschar *name, + const u32 name_len, const IGNORE_CASE_BOOL ic, + const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx) { ATTR_RECORD *a; ntfs_volume *vol; @@ -1228,21 +1236,21 @@ le32_to_cpu(ctx->mrec->bytes_allocated)) break; ctx->attr = a; - /* We catch $END with this more general check, too... */ - if (le32_to_cpu(a->type) > le32_to_cpu(type)) - return FALSE; + if (unlikely(le32_to_cpu(a->type) > le32_to_cpu(type) || + a->type == AT_END)) + return -ENOENT; if (unlikely(!a->length)) break; if (a->type != type) continue; /* - * If @name is present, compare the two names. If @name is + * If @name is present, compare the two names. If @name is * missing, assume we want an unnamed attribute. */ if (!name) { /* The search failed if the found attribute is named. */ if (a->name_length) - return FALSE; + return -ENOENT; } else if (!ntfs_are_names_equal(name, name_len, (ntfschar*)((u8*)a + le16_to_cpu(a->name_offset)), a->name_length, ic, upcase, upcase_len)) { @@ -1250,7 +1258,7 @@ rc = ntfs_collate_names(name, name_len, (ntfschar*)((u8*)a + - le16_to_cpu(a->name_offset)), + le16_to_cpu(a->name_offset)), a->name_length, 1, IGNORE_CASE, upcase, upcase_len); /* @@ -1258,56 +1266,55 @@ * matching attribute. */ if (rc == -1) - return FALSE; + return -ENOENT; /* If the strings are not equal, continue search. */ if (rc) continue; rc = ntfs_collate_names(name, name_len, (ntfschar*)((u8*)a + - le16_to_cpu(a->name_offset)), + le16_to_cpu(a->name_offset)), a->name_length, 1, CASE_SENSITIVE, upcase, upcase_len); if (rc == -1) - return FALSE; + return -ENOENT; if (rc) continue; } /* * The names match or @name not present and attribute is - * unnamed. If no @val specified, we have found the attribute + * unnamed. If no @val specified, we have found the attribute * and are done. */ if (!val) - return TRUE; + return 0; /* @val is present; compare values. */ else { - u32 vl; register int rc; - vl = le32_to_cpu(a->data.resident.value_length); - if (vl > val_len) - vl = val_len; - rc = memcmp(val, (u8*)a + le16_to_cpu( - a->data.resident.value_offset), vl); + a->data.resident.value_offset), + min_t(u32, val_len, le32_to_cpu( + a->data.resident.value_length))); /* * If @val collates before the current attribute's * value, there is no matching attribute. */ if (!rc) { register u32 avl; + avl = le32_to_cpu( a->data.resident.value_length); if (val_len == avl) - return TRUE; + return 0; if (val_len < avl) - return FALSE; + return -ENOENT; } else if (rc < 0) - return FALSE; + return -ENOENT; } } - ntfs_error(NULL, "Inode is corrupt. Run chkdsk."); - return FALSE; + ntfs_error(NULL, "Inode is corrupt. Run chkdsk."); + NVolSetErrors(vol); + return -EIO; } /** @@ -1419,7 +1426,7 @@ } /** - * find_external_attr - find an attribute in the attribute list of an ntfs inode + * ntfs_external_attr_find - find an attribute in the attribute list of an inode * @type: attribute type to find * @name: attribute name to find (optional, i.e. NULL means don't care) * @name_len: attribute name length (only needed if @name present) @@ -1429,34 +1436,49 @@ * @val_len: attribute value length * @ctx: search context with mft record and attribute to search from * - * You shouldn't need to call this function directly. Use lookup_attr() instead. + * You should not need to call this function directly. Use ntfs_attr_lookup() + * instead. * * Find an attribute by searching the attribute list for the corresponding - * attribute list entry. Having found the entry, map the mft record for read - * if the attribute is in a different mft record/inode, find_attr the attribute + * attribute list entry. Having found the entry, map the mft record if the + * attribute is in a different mft record/inode, ntfs_attr_find() the attribute * in there and return it. * * On first search @ctx->ntfs_ino must be the base mft record and @ctx must - * have been obtained from a call to get_attr_search_ctx(). On subsequent calls - * @ctx->ntfs_ino can be any extent inode, too (@ctx->base_ntfs_ino is then the - * base inode). + * have been obtained from a call to ntfs_attr_get_search_ctx(). On subsequent + * calls @ctx->ntfs_ino can be any extent inode, too (@ctx->base_ntfs_ino is + * then the base inode). * * After finishing with the attribute/mft record you need to call - * put_attr_search_ctx() to cleanup the search context (unmapping any mapped - * inodes, etc). + * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any + * mapped inodes, etc). * - * Return TRUE if the search was successful and FALSE if not. When TRUE, - * @ctx->attr is the found attribute and it is in mft record @ctx->mrec. When - * FALSE, @ctx->attr is the attribute which collates just after the attribute - * being searched for in the base ntfs inode, i.e. if one wants to add the - * attribute to the mft record this is the correct place to insert it into - * and if there is not enough space, the attribute should be placed in an - * extent mft record. + * If the attribute is found, ntfs_external_attr_find() returns 0 and + * @ctx->attr will point to the found attribute. @ctx->mrec will point to the + * mft record in which @ctx->attr is located and @ctx->al_entry will point to + * the attribute list entry for the attribute. + * + * If the attribute is not found, ntfs_external_attr_find() returns -ENOENT and + * @ctx->attr will point to the attribute in the base mft record before which + * the attribute being searched for would need to be inserted if such an action + * were to be desired. @ctx->mrec will point to the mft record in which + * @ctx->attr is located and @ctx->al_entry will point to the attribute list + * entry of the attribute before which the attribute being searched for would + * need to be inserted if such an action were to be desired. + * + * Thus to insert the not found attribute, one wants to add the attribute to + * @ctx->mrec (the base mft record) and if there is not enough space, the + * attribute should be placed in a newly allocated extent mft record. The + * attribute list entry for the inserted attribute should be inserted in the + * attribute list attribute at @ctx->al_entry. + * + * On actual error, ntfs_external_attr_find() returns -EIO. In this case + * @ctx->attr is undefined and in particular do not rely on it not changing. */ -static BOOL find_external_attr(const ATTR_TYPES type, const ntfschar *name, - const u32 name_len, const IGNORE_CASE_BOOL ic, - const VCN lowest_vcn, const u8 *val, const u32 val_len, - attr_search_context *ctx) +static int ntfs_external_attr_find(const ATTR_TYPES type, + const ntfschar *name, const u32 name_len, + const IGNORE_CASE_BOOL ic, const VCN lowest_vcn, + const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx) { ntfs_inode *base_ni, *ni; ntfs_volume *vol; @@ -1465,6 +1487,8 @@ ATTR_RECORD *a; ntfschar *al_name; u32 al_name_len; + int err = 0; + static const char *es = " Unmount and run chkdsk."; ni = ctx->ntfs_ino; base_ni = ctx->base_ntfs_ino; @@ -1476,6 +1500,8 @@ } if (ni == base_ni) ctx->base_attr = ctx->attr; + if (type == AT_END) + goto not_found; vol = base_ni->vol; al_start = base_ni->attr_list; al_end = al_start + base_ni->attr_list_size; @@ -1512,7 +1538,7 @@ if (type != al_entry->type) continue; /* - * If @name is present, compare the two names. If @name is + * If @name is present, compare the two names. If @name is * missing, assume we want an unnamed attribute. */ al_name_len = al_entry->name_length; @@ -1538,10 +1564,11 @@ continue; /* * FIXME: Reverse engineering showed 0, IGNORE_CASE but - * that is inconsistent with find_attr(). The subsequent - * rc checks were also different. Perhaps I made a - * mistake in one of the two. Need to recheck which is - * correct or at least see what is going on... (AIA) + * that is inconsistent with ntfs_attr_find(). The + * subsequent rc checks were also different. Perhaps I + * made a mistake in one of the two. Need to recheck + * which is correct or at least see what is going on... + * (AIA) */ rc = ntfs_collate_names(name, name_len, al_name, al_name_len, 1, CASE_SENSITIVE, @@ -1553,8 +1580,8 @@ } /* * The names match or @name not present and attribute is - * unnamed. Now check @lowest_vcn. Continue search if the - * next attribute list entry still fits @lowest_vcn. Otherwise + * unnamed. Now check @lowest_vcn. Continue search if the + * next attribute list entry still fits @lowest_vcn. Otherwise * we have reached the right one or the search has failed. */ if (lowest_vcn && (u8*)next_al_entry >= al_start && @@ -1562,7 +1589,7 @@ (u8*)next_al_entry + le16_to_cpu( next_al_entry->length) <= al_end && sle64_to_cpu(next_al_entry->lowest_vcn) <= - sle64_to_cpu(lowest_vcn) && + lowest_vcn && next_al_entry->type == al_entry->type && next_al_entry->name_length == al_name_len && ntfs_are_names_equal((ntfschar*)((u8*) @@ -1575,7 +1602,10 @@ if (MREF_LE(al_entry->mft_reference) == ni->mft_no) { if (MSEQNO_LE(al_entry->mft_reference) != ni->seq_no) { ntfs_error(vol->sb, "Found stale mft " - "reference in attribute list!"); + "reference in attribute list " + "of base inode 0x%lx.%s", + base_ni->mft_no, es); + err = -EIO; break; } } else { /* Mft references do not match. */ @@ -1593,10 +1623,16 @@ al_entry->mft_reference, &ni); ctx->ntfs_ino = ni; if (IS_ERR(ctx->mrec)) { - ntfs_error(vol->sb, "Failed to map mft " - "record, error code " - "%ld.", - -PTR_ERR(ctx->mrec)); + ntfs_error(vol->sb, "Failed to map " + "extent mft record " + "0x%lx of base inode " + "0x%lx.%s", + MREF_LE(al_entry-> + mft_reference), + base_ni->mft_no, es); + err = PTR_ERR(ctx->mrec); + if (err == -ENOENT) + err = -EIO; break; } } @@ -1609,14 +1645,14 @@ * current al_entry. */ /* - * We could call into find_attr() to find the right attribute - * in this mft record but this would be less efficient and not - * quite accurate as find_attr() ignores the attribute instance - * numbers for example which become important when one plays - * with attribute lists. Also, because a proper match has been - * found in the attribute list entry above, the comparison can - * now be optimized. So it is worth re-implementing a - * simplified find_attr() here. + * We could call into ntfs_attr_find() to find the right + * attribute in this mft record but this would be less + * efficient and not quite accurate as ntfs_attr_find() ignores + * the attribute instance numbers for example which become + * important when one plays with attribute lists. Also, + * because a proper match has been found in the attribute list + * entry above, the comparison can now be optimized. So it is + * worth re-implementing a simplified ntfs_attr_find() here. */ a = ctx->attr; /* @@ -1633,18 +1669,18 @@ break; if (al_entry->instance != a->instance) goto do_next_attr; + /* + * If the type and/or the name are mismatched between the + * attribute list entry and the attribute record, there is + * corruption so we break and return error EIO. + */ if (al_entry->type != a->type) - continue; - if (name) { - if (a->name_length != al_name_len) - continue; - if (!ntfs_are_names_equal((ntfschar*)((u8*)a + - le16_to_cpu(a->name_offset)), - a->name_length, al_name, al_name_len, - CASE_SENSITIVE, vol->upcase, - vol->upcase_len)) - continue; - } + break; + if (!ntfs_are_names_equal((ntfschar*)((u8*)a + + le16_to_cpu(a->name_offset)), a->name_length, + al_name, al_name_len, CASE_SENSITIVE, + vol->upcase, vol->upcase_len)) + break; ctx->attr = a; /* * If no @val specified or @val specified and it matches, we @@ -1656,46 +1692,76 @@ le16_to_cpu(a->data.resident.value_offset), val, val_len))) { ntfs_debug("Done, found."); - return TRUE; + return 0; } do_next_attr: /* Proceed to the next attribute in the current mft record. */ a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length)); goto do_next_attr_loop; } - ntfs_error(base_ni->vol->sb, "Inode contains corrupt attribute list " - "attribute."); + if (!err) { + ntfs_error(vol->sb, "Base inode 0x%lx contains corrupt " + "attribute list attribute.%s", base_ni->mft_no, + es); + err = -EIO; + } if (ni != base_ni) { unmap_extent_mft_record(ni); ctx->ntfs_ino = base_ni; ctx->mrec = ctx->base_mrec; ctx->attr = ctx->base_attr; } + if (err != -ENOMEM) + NVolSetErrors(vol); + return err; +not_found: /* - * FIXME: We absolutely have to return ERROR status instead of just - * false or we will blow up or even worse cause corruption when we add - * write support and we reach this code path! + * If we were looking for AT_END, we reset the search context @ctx and + * use ntfs_attr_find() to seek to the end of the base mft record. */ - printk(KERN_CRIT "NTFS: FIXME: Hit unfinished error code path!!!\n"); - return FALSE; -not_found: + if (type == AT_END) { + ntfs_attr_reinit_search_ctx(ctx); + return ntfs_attr_find(AT_END, name, name_len, ic, val, val_len, + ctx); + } /* - * Seek to the end of the base mft record, i.e. when we return false, - * ctx->mrec and ctx->attr indicate where the attribute should be - * inserted into the attribute record. - * And of course ctx->al_entry points to the end of the attribute - * list inside NTFS_I(ctx->base_vfs_ino)->attr_list. - * - * FIXME: Do we really want to do this here? Think about it... (AIA) + * The attribute was not found. Before we return, we want to ensure + * @ctx->mrec and @ctx->attr indicate the position at which the + * attribute should be inserted in the base mft record. Since we also + * want to preserve @ctx->al_entry we cannot reinitialize the search + * context using ntfs_attr_reinit_search_ctx() as this would set + * @ctx->al_entry to NULL. Thus we do the necessary bits manually (see + * ntfs_attr_init_search_ctx() below). Note, we _only_ preserve + * @ctx->al_entry as the remaining fields (base_*) are identical to + * their non base_ counterparts and we cannot set @ctx->base_attr + * correctly yet as we do not know what @ctx->attr will be set to by + * the call to ntfs_attr_find() below. */ - reinit_attr_search_ctx(ctx); - find_attr(type, name, name_len, ic, val, val_len, ctx); + ctx->mrec = ctx->base_mrec; + ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec + + le16_to_cpu(ctx->mrec->attrs_offset)); + ctx->is_first = TRUE; + ctx->ntfs_ino = ctx->base_ntfs_ino; + ctx->base_ntfs_ino = NULL; + ctx->base_mrec = NULL; + ctx->base_attr = NULL; + /* + * In case there are multiple matches in the base mft record, need to + * keep enumerating until we get an attribute not found response (or + * another error), otherwise we would keep returning the same attribute + * over and over again and all programs using us for enumeration would + * lock up in a tight loop. + */ + do { + err = ntfs_attr_find(type, name, name_len, ic, val, val_len, + ctx); + } while (!err); ntfs_debug("Done, not found."); - return FALSE; + return err; } /** - * lookup_attr - find an attribute in an ntfs inode + * ntfs_attr_lookup - find an attribute in an ntfs inode * @type: attribute type to find * @name: attribute name to find (optional, i.e. NULL means don't care) * @name_len: attribute name length (only needed if @name present) @@ -1705,27 +1771,38 @@ * @val_len: attribute value length * @ctx: search context with mft record and attribute to search from * - * Find an attribute in an ntfs inode. On first search @ctx->ntfs_ino must + * Find an attribute in an ntfs inode. On first search @ctx->ntfs_ino must * be the base mft record and @ctx must have been obtained from a call to - * get_attr_search_ctx(). + * ntfs_attr_get_search_ctx(). * * This function transparently handles attribute lists and @ctx is used to * continue searches where they were left off at. * * After finishing with the attribute/mft record you need to call - * put_attr_search_ctx() to cleanup the search context (unmapping any mapped - * inodes, etc). + * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any + * mapped inodes, etc). + * + * Return 0 if the search was successful and -errno if not. * - * Return TRUE if the search was successful and FALSE if not. When TRUE, - * @ctx->attr is the found attribute and it is in mft record @ctx->mrec. When - * FALSE, @ctx->attr is the attribute which collates just after the attribute - * being searched for, i.e. if one wants to add the attribute to the mft - * record this is the correct place to insert it into. + * When 0, @ctx->attr is the found attribute and it is in mft record + * @ctx->mrec. If an attribute list attribute is present, @ctx->al_entry is + * the attribute list entry of the found attribute. + * + * When -ENOENT, @ctx->attr is the attribute which collates just after the + * attribute being searched for, i.e. if one wants to add the attribute to the + * mft record this is the correct place to insert it into. If an attribute + * list attribute is present, @ctx->al_entry is the attribute list entry which + * collates just after the attribute list entry of the attribute being searched + * for, i.e. if one wants to add the attribute to the mft record this is the + * correct place to insert its attribute list entry into. + * + * When -errno != -ENOENT, an error occured during the lookup. @ctx->attr is + * then undefined and in particular you should not rely on it not changing. */ -BOOL lookup_attr(const ATTR_TYPES type, const ntfschar *name, +int ntfs_attr_lookup(const ATTR_TYPES type, const ntfschar *name, const u32 name_len, const IGNORE_CASE_BOOL ic, const VCN lowest_vcn, const u8 *val, const u32 val_len, - attr_search_context *ctx) + ntfs_attr_search_ctx *ctx) { ntfs_inode *base_ni; @@ -1736,21 +1813,22 @@ base_ni = ctx->ntfs_ino; /* Sanity check, just for debugging really. */ BUG_ON(!base_ni); - if (!NInoAttrList(base_ni)) - return find_attr(type, name, name_len, ic, val, val_len, ctx); - return find_external_attr(type, name, name_len, ic, lowest_vcn, val, - val_len, ctx); + if (!NInoAttrList(base_ni) || type == AT_ATTRIBUTE_LIST) + return ntfs_attr_find(type, name, name_len, ic, val, val_len, + ctx); + return ntfs_external_attr_find(type, name, name_len, ic, lowest_vcn, + val, val_len, ctx); } /** - * init_attr_search_ctx - initialize an attribute search context + * ntfs_attr_init_search_ctx - initialize an attribute search context * @ctx: attribute search context to initialize * @ni: ntfs inode with which to initialize the search context * @mrec: mft record with which to initialize the search context * * Initialize the attribute search context @ctx with @ni and @mrec. */ -static inline void init_attr_search_ctx(attr_search_context *ctx, +static inline void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx, ntfs_inode *ni, MFT_RECORD *mrec) { ctx->mrec = mrec; @@ -1765,7 +1843,7 @@ } /** - * reinit_attr_search_ctx - reinitialize an attribute search context + * ntfs_attr_reinit_search_ctx - reinitialize an attribute search context * @ctx: attribute search context to reinitialize * * Reinitialize the attribute search context @ctx, unmapping an associated @@ -1774,7 +1852,7 @@ * This is used when a search for a new attribute is being started to reset * the search context to the beginning. */ -void reinit_attr_search_ctx(attr_search_context *ctx) +void ntfs_attr_reinit_search_ctx(ntfs_attr_search_ctx *ctx) { if (likely(!ctx->base_ntfs_ino)) { /* No attribute list. */ @@ -1786,40 +1864,39 @@ } /* Attribute list. */ if (ctx->ntfs_ino != ctx->base_ntfs_ino) unmap_extent_mft_record(ctx->ntfs_ino); - init_attr_search_ctx(ctx, ctx->base_ntfs_ino, ctx->base_mrec); + ntfs_attr_init_search_ctx(ctx, ctx->base_ntfs_ino, ctx->base_mrec); return; } /** - * get_attr_search_ctx - allocate and initialize a new attribute search context + * ntfs_attr_get_search_ctx - allocate/initialize a new attribute search context * @ni: ntfs inode with which to initialize the search context * @mrec: mft record with which to initialize the search context * * Allocate a new attribute search context, initialize it with @ni and @mrec, * and return it. Return NULL if allocation failed. */ -attr_search_context *get_attr_search_ctx(ntfs_inode *ni, MFT_RECORD *mrec) +ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni, MFT_RECORD *mrec) { - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; ctx = kmem_cache_alloc(ntfs_attr_ctx_cache, SLAB_NOFS); if (ctx) - init_attr_search_ctx(ctx, ni, mrec); + ntfs_attr_init_search_ctx(ctx, ni, mrec); return ctx; } /** - * put_attr_search_ctx - release an attribute search context + * ntfs_attr_put_search_ctx - release an attribute search context * @ctx: attribute search context to free * * Release the attribute search context @ctx, unmapping an associated extent * mft record if present. */ -void put_attr_search_ctx(attr_search_context *ctx) +void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx) { if (ctx->base_ntfs_ino && ctx->ntfs_ino != ctx->base_ntfs_ino) unmap_extent_mft_record(ctx->ntfs_ino); kmem_cache_free(ntfs_attr_ctx_cache, ctx); return; } - diff -Nru a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h --- a/fs/ntfs/attrib.h 2004-09-21 21:06:35 -07:00 +++ b/fs/ntfs/attrib.h 2004-09-21 21:06:35 -07:00 @@ -43,10 +43,10 @@ } LCN_SPECIAL_VALUES; /** - * attr_search_context - used in attribute search functions + * ntfs_attr_search_ctx - used in attribute search functions * @mrec: buffer containing mft record to search * @attr: attribute record in @mrec where to begin/continue search - * @is_first: if true lookup_attr() begins search with @attr, else after @attr + * @is_first: if true ntfs_attr_lookup() begins search with @attr, else after * * Structure must be initialized to zero before the first call to one of the * attribute search functions. Initialize @mrec to point to the mft record to @@ -69,7 +69,7 @@ ntfs_inode *base_ntfs_ino; MFT_RECORD *base_mrec; ATTR_RECORD *base_attr; -} attr_search_context; +} ntfs_attr_search_ctx; extern runlist_element *decompress_mapping_pairs(const ntfs_volume *vol, const ATTR_RECORD *attr, runlist_element *old_rl); @@ -81,14 +81,10 @@ extern runlist_element *ntfs_find_vcn(ntfs_inode *ni, const VCN vcn, const BOOL need_write); -extern BOOL find_attr(const ATTR_TYPES type, const ntfschar *name, - const u32 name_len, const IGNORE_CASE_BOOL ic, const u8 *val, - const u32 val_len, attr_search_context *ctx); - -BOOL lookup_attr(const ATTR_TYPES type, const ntfschar *name, +int ntfs_attr_lookup(const ATTR_TYPES type, const ntfschar *name, const u32 name_len, const IGNORE_CASE_BOOL ic, const VCN lowest_vcn, const u8 *val, const u32 val_len, - attr_search_context *ctx); + ntfs_attr_search_ctx *ctx); extern int load_attribute_list(ntfs_volume *vol, runlist *rl, u8 *al_start, const s64 size, const s64 initialized_size); @@ -100,9 +96,9 @@ return sle64_to_cpu(a->data.non_resident.data_size); } -extern void reinit_attr_search_ctx(attr_search_context *ctx); -extern attr_search_context *get_attr_search_ctx(ntfs_inode *ni, +extern void ntfs_attr_reinit_search_ctx(ntfs_attr_search_ctx *ctx); +extern ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni, MFT_RECORD *mrec); -extern void put_attr_search_ctx(attr_search_context *ctx); +extern void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx); #endif /* _LINUX_NTFS_ATTRIB_H */ diff -Nru a/fs/ntfs/debug.c b/fs/ntfs/debug.c --- a/fs/ntfs/debug.c 2004-09-21 21:06:35 -07:00 +++ b/fs/ntfs/debug.c 2004-09-21 21:06:35 -07:00 @@ -127,7 +127,7 @@ va_start(args, fmt); vsnprintf(err_buf, sizeof(err_buf), fmt, args); va_end(args); - printk(KERN_DEBUG "NTFS-fs DEBUG (%s, %d): %s: %s\n", + printk(KERN_DEBUG "NTFS-fs DEBUG (%s, %d): %s(): %s\n", file, line, flen ? function : "", err_buf); spin_unlock(&err_buf_lock); } diff -Nru a/fs/ntfs/dir.c b/fs/ntfs/dir.c --- a/fs/ntfs/dir.c 2004-09-21 21:06:35 -07:00 +++ b/fs/ntfs/dir.c 2004-09-21 21:06:35 -07:00 @@ -83,7 +83,7 @@ INDEX_ALLOCATION *ia; u8 *index_end; u64 mref; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; int err, rc; VCN vcn, old_vcn; struct address_space *ia_mapping; @@ -100,17 +100,21 @@ -PTR_ERR(m)); return ERR_MREF(PTR_ERR(m)); } - ctx = get_attr_search_ctx(dir_ni, m); + ctx = ntfs_attr_get_search_ctx(dir_ni, m); if (unlikely(!ctx)) { err = -ENOMEM; goto err_out; } /* Find the index root attribute in the mft record. */ - if (!lookup_attr(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL, 0, - ctx)) { - ntfs_error(sb, "Index root attribute missing in directory " - "inode 0x%lx.", dir_ni->mft_no); - err = -EIO; + err = ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL, + 0, ctx); + if (unlikely(err)) { + if (err == -ENOENT) { + ntfs_error(sb, "Index root attribute missing in " + "directory inode 0x%lx.", + dir_ni->mft_no); + err = -EIO; + } goto err_out; } /* Get to the index root value (it's been verified in read_inode). */ @@ -179,7 +183,7 @@ *res = NULL; } mref = le64_to_cpu(ie->data.dir.indexed_file); - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(dir_ni); return mref; } @@ -278,7 +282,7 @@ */ if (!(ie->flags & INDEX_ENTRY_NODE)) { if (name) { - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(dir_ni); return name->mref; } @@ -301,7 +305,7 @@ * We are done with the index root and the mft record. Release them, * otherwise we deadlock with ntfs_map_page(). */ - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(dir_ni); m = NULL; ctx = NULL; @@ -582,7 +586,7 @@ ntfs_unmap_page(page); err_out: if (ctx) - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); if (m) unmap_mft_record(dir_ni); if (name) { @@ -634,7 +638,7 @@ INDEX_ALLOCATION *ia; u8 *index_end; u64 mref; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; int err, rc; IGNORE_CASE_BOOL ic; VCN vcn, old_vcn; @@ -649,17 +653,21 @@ -PTR_ERR(m)); return ERR_MREF(PTR_ERR(m)); } - ctx = get_attr_search_ctx(dir_ni, m); + ctx = ntfs_attr_get_search_ctx(dir_ni, m); if (!ctx) { err = -ENOMEM; goto err_out; } /* Find the index root attribute in the mft record. */ - if (!lookup_attr(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL, 0, - ctx)) { - ntfs_error(sb, "Index root attribute missing in directory " - "inode 0x%lx.", dir_ni->mft_no); - err = -EIO; + err = ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL, + 0, ctx); + if (unlikely(err)) { + if (err == -ENOENT) { + ntfs_error(sb, "Index root attribute missing in " + "directory inode 0x%lx.", + dir_ni->mft_no); + err = -EIO; + } goto err_out; } /* Get to the index root value (it's been verified in read_inode). */ @@ -710,7 +718,7 @@ vol->upcase, vol->upcase_len)) { found_it: mref = le64_to_cpu(ie->data.dir.indexed_file); - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(dir_ni); return mref; } @@ -776,7 +784,7 @@ * We are done with the index root and the mft record. Release them, * otherwise we deadlock with ntfs_map_page(). */ - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(dir_ni); m = NULL; ctx = NULL; @@ -979,7 +987,7 @@ ntfs_unmap_page(page); err_out: if (ctx) - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); if (m) unmap_mft_record(dir_ni); return ERR_MREF(err); @@ -1125,7 +1133,7 @@ struct address_space *ia_mapping, *bmp_mapping; struct page *bmp_page = NULL, *ia_page = NULL; u8 *kaddr, *bmp, *index_end; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; fpos = filp->f_pos; ntfs_debug("Entering for inode 0x%lx, fpos 0x%llx.", @@ -1175,7 +1183,7 @@ m = NULL; goto err_out; } - ctx = get_attr_search_ctx(ndir, m); + ctx = ntfs_attr_get_search_ctx(ndir, m); if (unlikely(!ctx)) { err = -ENOMEM; goto err_out; @@ -1183,8 +1191,9 @@ /* Get the offset into the index root attribute. */ ir_pos = (s64)fpos; /* Find the index root attribute in the mft record. */ - if (unlikely(!lookup_attr(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, - NULL, 0, ctx))) { + err = ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL, + 0, ctx); + if (unlikely(err)) { ntfs_error(sb, "Index root attribute missing in directory " "inode 0x%lx.", vdir->i_ino); goto err_out; @@ -1208,7 +1217,7 @@ /* Copy the index root value (it has been verified in read_inode). */ memcpy(ir, (u8*)ctx->attr + le16_to_cpu(ctx->attr->data.resident.value_offset), rc); - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(ndir); ctx = NULL; m = NULL; @@ -1460,7 +1469,7 @@ if (name) kfree(name); if (ctx) - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); if (m) unmap_mft_record(ndir); if (!err) diff -Nru a/fs/ntfs/index.c b/fs/ntfs/index.c --- a/fs/ntfs/index.c 2004-09-21 21:06:35 -07:00 +++ b/fs/ntfs/index.c 2004-09-21 21:06:35 -07:00 @@ -65,7 +65,7 @@ if (ictx->entry) { if (ictx->is_in_root) { if (ictx->actx) - put_attr_search_ctx(ictx->actx); + ntfs_attr_put_search_ctx(ictx->actx); if (ictx->base_ni) unmap_mft_record(ictx->base_ni); } else { @@ -125,6 +125,7 @@ int ntfs_index_lookup(const void *key, const int key_len, ntfs_index_context *ictx) { + VCN vcn, old_vcn; ntfs_inode *idx_ni = ictx->idx_ni; ntfs_volume *vol = idx_ni->vol; struct super_block *sb = vol->sb; @@ -133,13 +134,11 @@ INDEX_ROOT *ir; INDEX_ENTRY *ie; INDEX_ALLOCATION *ia; - u8 *index_end; - attr_search_context *actx; - int rc, err = 0; - VCN vcn, old_vcn; + u8 *index_end, *kaddr; + ntfs_attr_search_ctx *actx; struct address_space *ia_mapping; struct page *page; - u8 *kaddr; + int rc, err = 0; ntfs_debug("Entering."); BUG_ON(!NInoAttr(idx_ni)); @@ -162,17 +161,20 @@ -PTR_ERR(m)); return PTR_ERR(m); } - actx = get_attr_search_ctx(base_ni, m); + actx = ntfs_attr_get_search_ctx(base_ni, m); if (unlikely(!actx)) { err = -ENOMEM; goto err_out; } /* Find the index root attribute in the mft record. */ - if (!lookup_attr(AT_INDEX_ROOT, idx_ni->name, idx_ni->name_len, - CASE_SENSITIVE, 0, NULL, 0, actx)) { - ntfs_error(sb, "Index root attribute missing in inode 0x%lx.", - idx_ni->mft_no); - err = -EIO; + err = ntfs_attr_lookup(AT_INDEX_ROOT, idx_ni->name, idx_ni->name_len, + CASE_SENSITIVE, 0, NULL, 0, actx); + if (unlikely(err)) { + if (err == -ENOENT) { + ntfs_error(sb, "Index root attribute missing in inode " + "0x%lx.", idx_ni->mft_no); + err = -EIO; + } goto err_out; } /* Get to the index root value (it has been verified in read_inode). */ @@ -269,7 +271,7 @@ * We are done with the index root and the mft record. Release them, * otherwise we deadlock with ntfs_map_page(). */ - put_attr_search_ctx(actx); + ntfs_attr_put_search_ctx(actx); unmap_mft_record(base_ni); m = NULL; actx = NULL; @@ -448,7 +450,7 @@ ntfs_unmap_page(page); err_out: if (actx) - put_attr_search_ctx(actx); + ntfs_attr_put_search_ctx(actx); if (m) unmap_mft_record(base_ni); return err; diff -Nru a/fs/ntfs/index.h b/fs/ntfs/index.h --- a/fs/ntfs/index.h 2004-09-21 21:06:35 -07:00 +++ b/fs/ntfs/index.h 2004-09-21 21:06:35 -07:00 @@ -78,7 +78,7 @@ u16 data_len; BOOL is_in_root; INDEX_ROOT *ir; - attr_search_context *actx; + ntfs_attr_search_ctx *actx; ntfs_inode *base_ni; INDEX_ALLOCATION *ia; struct page *page; diff -Nru a/fs/ntfs/inode.c b/fs/ntfs/inode.c --- a/fs/ntfs/inode.c 2004-09-21 21:06:35 -07:00 +++ b/fs/ntfs/inode.c 2004-09-21 21:06:35 -07:00 @@ -428,20 +428,21 @@ * Return values: * 1: file is in $Extend directory * 0: file is not in $Extend directory - * -EIO: file is corrupt + * -errno: failed to determine if the file is in the $Extend directory */ -static int ntfs_is_extended_system_file(attr_search_context *ctx) +static int ntfs_is_extended_system_file(ntfs_attr_search_ctx *ctx) { - int nr_links; + int nr_links, err; /* Restart search. */ - reinit_attr_search_ctx(ctx); + ntfs_attr_reinit_search_ctx(ctx); /* Get number of hard links. */ nr_links = le16_to_cpu(ctx->mrec->link_count); /* Loop through all hard links. */ - while (lookup_attr(AT_FILE_NAME, NULL, 0, 0, 0, NULL, 0, ctx)) { + while (!(err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0, NULL, 0, + ctx))) { FILE_NAME_ATTR *file_name_attr; ATTR_RECORD *attr = ctx->attr; u8 *p, *p2; @@ -484,7 +485,9 @@ if (MREF_LE(file_name_attr->parent_directory) == FILE_Extend) return 1; /* YES, it's an extended system file. */ } - if (nr_links) { + if (unlikely(err != -ENOENT)) + return err; + if (unlikely(nr_links)) { ntfs_error(ctx->ntfs_ino->vol->sb, "Inode hard link count " "doesn't match number of name attributes. You " "should run chkdsk."); @@ -525,7 +528,7 @@ ntfs_inode *ni; MFT_RECORD *m; STANDARD_INFORMATION *si; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; int err = 0; ntfs_debug("Entering for i_ino 0x%lx.", vi->i_ino); @@ -557,7 +560,7 @@ err = PTR_ERR(m); goto err_out; } - ctx = get_attr_search_ctx(ni, m); + ctx = ntfs_attr_get_search_ctx(ni, m); if (!ctx) { err = -ENOMEM; goto unm_err_out; @@ -608,14 +611,18 @@ * in fact fail if the standard information is in an extent record, but * I don't think this actually ever happens. */ - if (!lookup_attr(AT_STANDARD_INFORMATION, NULL, 0, 0, 0, NULL, 0, - ctx)) { - /* - * TODO: We should be performing a hot fix here (if the recover - * mount option is set) by creating a new attribute. - */ - ntfs_error(vi->i_sb, "$STANDARD_INFORMATION attribute is " - "missing."); + err = ntfs_attr_lookup(AT_STANDARD_INFORMATION, NULL, 0, 0, 0, NULL, 0, + ctx); + if (unlikely(err)) { + if (err == -ENOENT) { + /* + * TODO: We should be performing a hot fix here (if the + * recover mount option is set) by creating a new + * attribute. + */ + ntfs_error(vi->i_sb, "$STANDARD_INFORMATION attribute " + "is missing."); + } goto unm_err_out; } /* Get the standard information attribute value. */ @@ -646,8 +653,15 @@ vi->i_atime = ntfs2utc(si->last_access_time); /* Find the attribute list attribute if present. */ - reinit_attr_search_ctx(ctx); - if (lookup_attr(AT_ATTRIBUTE_LIST, NULL, 0, 0, 0, NULL, 0, ctx)) { + ntfs_attr_reinit_search_ctx(ctx); + err = ntfs_attr_lookup(AT_ATTRIBUTE_LIST, NULL, 0, 0, 0, NULL, 0, ctx); + if (err) { + if (unlikely(err != -ENOENT)) { + ntfs_error(vi->i_sb, "Failed to lookup attribute list " + "attribute. You should run chkdsk."); + goto unm_err_out; + } + } else /* if (!err) */ { if (vi->i_ino == FILE_MFT) goto skip_attr_list_load; ntfs_debug("Attribute list found in inode 0x%lx.", vi->i_ino); @@ -733,13 +747,17 @@ char *ir_end, *index_end; /* It is a directory, find index root attribute. */ - reinit_attr_search_ctx(ctx); - if (!lookup_attr(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, - NULL, 0, ctx)) { - // FIXME: File is corrupt! Hot-fix with empty index - // root attribute if recovery option is set. - ntfs_error(vi->i_sb, "$INDEX_ROOT attribute is " - "missing."); + ntfs_attr_reinit_search_ctx(ctx); + err = ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, + 0, NULL, 0, ctx); + if (unlikely(err)) { + if (err == -ENOENT) { + // FIXME: File is corrupt! Hot-fix with empty + // index root attribute if recovery option is + // set. + ntfs_error(vi->i_sb, "$INDEX_ROOT attribute " + "is missing."); + } goto unm_err_out; } /* Set up the state. */ @@ -841,7 +859,7 @@ vi->i_size = ni->initialized_size = ni->allocated_size = 0; /* We are done with the mft record, so we release it. */ - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(ni); m = NULL; ctx = NULL; @@ -849,12 +867,19 @@ } /* LARGE_INDEX: Index allocation present. Setup state. */ NInoSetIndexAllocPresent(ni); /* Find index allocation attribute. */ - reinit_attr_search_ctx(ctx); - if (!lookup_attr(AT_INDEX_ALLOCATION, I30, 4, CASE_SENSITIVE, - 0, NULL, 0, ctx)) { - ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute " - "is not present but $INDEX_ROOT " - "indicated it is."); + ntfs_attr_reinit_search_ctx(ctx); + err = ntfs_attr_lookup(AT_INDEX_ALLOCATION, I30, 4, + CASE_SENSITIVE, 0, NULL, 0, ctx); + if (unlikely(err)) { + if (err == -ENOENT) + ntfs_error(vi->i_sb, "$INDEX_ALLOCATION " + "attribute is not present but " + "$INDEX_ROOT indicated it " + "is."); + else + ntfs_error(vi->i_sb, "Failed to lookup " + "$INDEX_ALLOCATION " + "attribute."); goto unm_err_out; } if (!ctx->attr->non_resident) { @@ -894,7 +919,7 @@ * We are done with the mft record, so we release it. Otherwise * we would deadlock in ntfs_attr_iget(). */ - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(ni); m = NULL; ctx = NULL; @@ -938,7 +963,7 @@ vi->i_mapping->a_ops = &ntfs_mst_aops; } else { /* It is a file. */ - reinit_attr_search_ctx(ctx); + ntfs_attr_reinit_search_ctx(ctx); /* Setup the data attribute, even if not present. */ ni->type = AT_DATA; @@ -946,9 +971,15 @@ ni->name_len = 0; /* Find first extent of the unnamed data attribute. */ - if (!lookup_attr(AT_DATA, NULL, 0, 0, 0, NULL, 0, ctx)) { + err = ntfs_attr_lookup(AT_DATA, NULL, 0, 0, 0, NULL, 0, ctx); + if (unlikely(err)) { vi->i_size = ni->initialized_size = - ni->allocated_size = 0LL; + ni->allocated_size = 0; + if (err != -ENOENT) { + ntfs_error(vi->i_sb, "Failed to lookup $DATA " + "attribute."); + goto unm_err_out; + } /* * FILE_Secure does not have an unnamed $DATA * attribute, so we special case it here. @@ -1059,7 +1090,7 @@ } no_data_attr_special_case: /* We are done with the mft record, so we release it. */ - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(ni); m = NULL; ctx = NULL; @@ -1098,7 +1129,7 @@ if (!err) err = -EIO; if (ctx) - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); if (m) unmap_mft_record(ni); err_out: @@ -1133,7 +1164,7 @@ ntfs_volume *vol = NTFS_SB(vi->i_sb); ntfs_inode *ni, *base_ni; MFT_RECORD *m; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; int err = 0; ntfs_debug("Entering for i_ino 0x%lx.", vi->i_ino); @@ -1162,15 +1193,16 @@ err = PTR_ERR(m); goto err_out; } - ctx = get_attr_search_ctx(base_ni, m); + ctx = ntfs_attr_get_search_ctx(base_ni, m); if (!ctx) { err = -ENOMEM; goto unm_err_out; } /* Find the attribute. */ - if (!lookup_attr(ni->type, ni->name, ni->name_len, CASE_SENSITIVE, 0, - NULL, 0, ctx)) + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, + CASE_SENSITIVE, 0, NULL, 0, ctx); + if (unlikely(err)) goto unm_err_out; if (!ctx->attr->non_resident) { @@ -1333,7 +1365,7 @@ ni->ext.base_ntfs_ino = base_ni; ni->nr_extents = -1; - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(base_ni); ntfs_debug("Done."); @@ -1343,7 +1375,7 @@ if (!err) err = -EIO; if (ctx) - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(base_ni); err_out: ntfs_error(vi->i_sb, "Failed with error code %i while reading " @@ -1392,7 +1424,7 @@ ntfs_inode *ni, *base_ni, *bni; struct inode *bvi; MFT_RECORD *m; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; INDEX_ROOT *ir; u8 *ir_end, *index_end; int err = 0; @@ -1419,15 +1451,18 @@ err = PTR_ERR(m); goto err_out; } - ctx = get_attr_search_ctx(base_ni, m); + ctx = ntfs_attr_get_search_ctx(base_ni, m); if (!ctx) { err = -ENOMEM; goto unm_err_out; } /* Find the index root attribute. */ - if (!lookup_attr(AT_INDEX_ROOT, ni->name, ni->name_len, CASE_SENSITIVE, - 0, NULL, 0, ctx)) { - ntfs_error(vi->i_sb, "$INDEX_ROOT attribute is missing."); + err = ntfs_attr_lookup(AT_INDEX_ROOT, ni->name, ni->name_len, + CASE_SENSITIVE, 0, NULL, 0, ctx); + if (unlikely(err)) { + if (err == -ENOENT) + ntfs_error(vi->i_sb, "$INDEX_ROOT attribute is " + "missing."); goto unm_err_out; } /* Set up the state. */ @@ -1497,7 +1532,7 @@ /* No index allocation. */ vi->i_size = ni->initialized_size = ni->allocated_size = 0; /* We are done with the mft record, so we release it. */ - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(base_ni); m = NULL; ctx = NULL; @@ -1505,11 +1540,17 @@ } /* LARGE_INDEX: Index allocation present. Setup state. */ NInoSetIndexAllocPresent(ni); /* Find index allocation attribute. */ - reinit_attr_search_ctx(ctx); - if (!lookup_attr(AT_INDEX_ALLOCATION, ni->name, ni->name_len, - CASE_SENSITIVE, 0, NULL, 0, ctx)) { - ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is not " - "present but $INDEX_ROOT indicated it is."); + ntfs_attr_reinit_search_ctx(ctx); + err = ntfs_attr_lookup(AT_INDEX_ALLOCATION, ni->name, ni->name_len, + CASE_SENSITIVE, 0, NULL, 0, ctx); + if (unlikely(err)) { + if (err == -ENOENT) + ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is " + "not present but $INDEX_ROOT " + "indicated it is."); + else + ntfs_error(vi->i_sb, "Failed to lookup " + "$INDEX_ALLOCATION attribute."); goto unm_err_out; } if (!ctx->attr->non_resident) { @@ -1546,7 +1587,7 @@ * We are done with the mft record, so we release it. Otherwise * we would deadlock in ntfs_attr_iget(). */ - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(base_ni); m = NULL; ctx = NULL; @@ -1597,7 +1638,7 @@ if (!err) err = -EIO; if (ctx) - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); if (m) unmap_mft_record(base_ni); err_out: @@ -1619,16 +1660,16 @@ * is not initialized and hence we cannot get at the contents of mft records * by calling map_mft_record*(). * - * Further it needs to cope with the circular references problem, i.e. can't + * Further it needs to cope with the circular references problem, i.e. cannot * load any attributes other than $ATTRIBUTE_LIST until $DATA is loaded, because - * we don't know where the other extent mft records are yet and again, because - * we cannot call map_mft_record*() yet. Obviously this applies only when an + * we do not know where the other extent mft records are yet and again, because + * we cannot call map_mft_record*() yet. Obviously this applies only when an * attribute list is actually present in $MFT inode. * * We solve these problems by starting with the $DATA attribute before anything - * else and iterating using lookup_attr($DATA) over all extents. As each extent - * is found, we decompress_mapping_pairs() including the implied - * merge_runlists(). Each step of the iteration necessarily provides + * else and iterating using ntfs_attr_lookup($DATA) over all extents. As each + * extent is found, we decompress_mapping_pairs() including the implied + * ntfs_merge_runlists(). Each step of the iteration necessarily provides * sufficient information for the next step to complete. * * This should work but there are two possible pit falls (see inline comments @@ -1644,7 +1685,7 @@ ntfs_inode *ni; MFT_RECORD *m = NULL; ATTR_RECORD *attr; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; unsigned int i, nr_blocks; int err; @@ -1719,14 +1760,21 @@ /* Provides readpage() and sync_page() for map_mft_record(). */ vi->i_mapping->a_ops = &ntfs_mft_aops; - ctx = get_attr_search_ctx(ni, m); + ctx = ntfs_attr_get_search_ctx(ni, m); if (!ctx) { err = -ENOMEM; goto err_out; } /* Find the attribute list attribute if present. */ - if (lookup_attr(AT_ATTRIBUTE_LIST, NULL, 0, 0, 0, NULL, 0, ctx)) { + err = ntfs_attr_lookup(AT_ATTRIBUTE_LIST, NULL, 0, 0, 0, NULL, 0, ctx); + if (err) { + if (unlikely(err != -ENOENT)) { + ntfs_error(sb, "Failed to lookup attribute list " + "attribute. You should run chkdsk."); + goto put_err_out; + } + } else /* if (!err) */ { ATTR_LIST_ENTRY *al_entry, *next_al_entry; u8 *al_end; @@ -1855,12 +1903,13 @@ } } - reinit_attr_search_ctx(ctx); + ntfs_attr_reinit_search_ctx(ctx); /* Now load all attribute extents. */ attr = NULL; next_vcn = last_vcn = highest_vcn = 0; - while (lookup_attr(AT_DATA, NULL, 0, 0, next_vcn, NULL, 0, ctx)) { + while (!(err = ntfs_attr_lookup(AT_DATA, NULL, 0, 0, next_vcn, NULL, 0, + ctx))) { runlist_element *nrl; /* Cache the current attribute. */ @@ -1900,8 +1949,6 @@ /* Are we in the first extent? */ if (!next_vcn) { - u64 ll; - if (attr->data.non_resident.lowest_vcn) { ntfs_error(sb, "First extent of $DATA " "attribute has non zero " @@ -1920,17 +1967,15 @@ non_resident.initialized_size); ni->allocated_size = sle64_to_cpu( attr->data.non_resident.allocated_size); - /* Set the number of mft records. */ - ll = vi->i_size >> vol->mft_record_size_bits; /* * Verify the number of mft records does not exceed * 2^32 - 1. */ - if (ll >= (1ULL << 32)) { + if ((vi->i_size >> vol->mft_record_size_bits) >= + (1ULL << 32)) { ntfs_error(sb, "$MFT is too big! Aborting."); goto put_err_out; } - vol->nr_mft_records = ll; /* * We have got the first extent of the runlist for * $MFT which means it is now relatively safe to call @@ -1959,7 +2004,7 @@ "saw this message to " "linux-ntfs-dev@lists." "sourceforge.net"); - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); /* Revert to the safe super operations. */ ntfs_free(m); return -1; @@ -1995,21 +2040,26 @@ goto put_err_out; } } + if (err != -ENOENT) { + ntfs_error(sb, "Failed to lookup $MFT/$DATA attribute extent. " + "$MFT is corrupt. Run chkdsk."); + goto put_err_out; + } if (!attr) { ntfs_error(sb, "$MFT/$DATA attribute not found. $MFT is " "corrupt. Run chkdsk."); goto put_err_out; } if (highest_vcn && highest_vcn != last_vcn - 1) { - ntfs_error(sb, "Failed to load the complete runlist " - "for $MFT/$DATA. Driver bug or " - "corrupt $MFT. Run chkdsk."); + ntfs_error(sb, "Failed to load the complete runlist for " + "$MFT/$DATA. Driver bug or corrupt $MFT. " + "Run chkdsk."); ntfs_debug("highest_vcn = 0x%llx, last_vcn - 1 = 0x%llx", (unsigned long long)highest_vcn, (unsigned long long)last_vcn - 1); goto put_err_out; } - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); ntfs_debug("Done."); ntfs_free(m); return 0; @@ -2018,7 +2068,7 @@ ntfs_error(sb, "Couldn't find first extent of $DATA attribute in " "attribute list. $MFT is corrupt. Run chkdsk."); put_err_out: - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); err_out: ntfs_error(sb, "Failed. Marking inode as bad."); make_bad_inode(vi); @@ -2321,7 +2371,7 @@ { s64 nt; ntfs_inode *ni = NTFS_I(vi); - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; MFT_RECORD *m; STANDARD_INFORMATION *si; int err = 0; @@ -2346,15 +2396,15 @@ goto err_out; } /* Update the access times in the standard information attribute. */ - ctx = get_attr_search_ctx(ni, m); + ctx = ntfs_attr_get_search_ctx(ni, m); if (unlikely(!ctx)) { err = -ENOMEM; goto unm_err_out; } - if (unlikely(!lookup_attr(AT_STANDARD_INFORMATION, NULL, 0, - CASE_SENSITIVE, 0, NULL, 0, ctx))) { - put_attr_search_ctx(ctx); - err = -ENOENT; + err = ntfs_attr_lookup(AT_STANDARD_INFORMATION, NULL, 0, + CASE_SENSITIVE, 0, NULL, 0, ctx); + if (unlikely(err)) { + ntfs_attr_put_search_ctx(ctx); goto unm_err_out; } si = (STANDARD_INFORMATION*)((u8*)ctx->attr + @@ -2399,7 +2449,7 @@ */ if (modified && !NInoTestSetDirty(ctx->ntfs_ino)) __set_page_dirty_nobuffers(ctx->ntfs_ino->page); - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); /* Now the access times are updated, write the base mft record. */ if (NInoDirty(ni)) err = write_mft_record(ni, m, sync); diff -Nru a/fs/ntfs/mft.c b/fs/ntfs/mft.c --- a/fs/ntfs/mft.c 2004-09-21 21:06:35 -07:00 +++ b/fs/ntfs/mft.c 2004-09-21 21:06:35 -07:00 @@ -418,7 +418,8 @@ m = ERR_PTR(-ENOMEM); goto unm_err_out; } - if (base_ni->ext.extent_ntfs_inos) { + if (base_ni->nr_extents) { + BUG_ON(!base_ni->ext.extent_ntfs_inos); memcpy(tmp, base_ni->ext.extent_ntfs_inos, new_size - 4 * sizeof(ntfs_inode *)); kfree(base_ni->ext.extent_ntfs_inos); diff -Nru a/fs/ntfs/namei.c b/fs/ntfs/namei.c --- a/fs/ntfs/namei.c 2004-09-21 21:06:35 -07:00 +++ b/fs/ntfs/namei.c 2004-09-21 21:06:35 -07:00 @@ -171,7 +171,7 @@ { struct dentry *real_dent, *new_dent; MFT_RECORD *m; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; ntfs_inode *ni = NTFS_I(dent_inode); int err; struct qstr nls_name; @@ -196,8 +196,8 @@ ctx = NULL; goto err_out; } - ctx = get_attr_search_ctx(ni, m); - if (!ctx) { + ctx = ntfs_attr_get_search_ctx(ni, m); + if (unlikely(!ctx)) { err = -ENOMEM; goto err_out; } @@ -205,12 +205,14 @@ ATTR_RECORD *a; u32 val_len; - if (!lookup_attr(AT_FILE_NAME, NULL, 0, 0, 0, NULL, 0, - ctx)) { + err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0, + NULL, 0, ctx); + if (unlikely(err)) { ntfs_error(vol->sb, "Inode corrupt: No WIN32 " "namespace counterpart to DOS " "file name. Run chkdsk."); - err = -EIO; + if (err == -ENOENT) + err = -EIO; goto err_out; } /* Consistency checks. */ @@ -233,7 +235,7 @@ (ntfschar*)&fn->file_name, fn->file_name_length, (unsigned char**)&nls_name.name, 0); - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(ni); } m = NULL; @@ -329,7 +331,7 @@ err = -EIO; err_out: if (ctx) - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); if (m) unmap_mft_record(ni); iput(dent_inode); @@ -366,12 +368,13 @@ struct inode *vi = child_dent->d_inode; ntfs_inode *ni = NTFS_I(vi); MFT_RECORD *mrec; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; ATTR_RECORD *attr; FILE_NAME_ATTR *fn; struct inode *parent_vi; struct dentry *parent_dent; unsigned long parent_ino; + int err; ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); /* Get the mft record of the inode belonging to the child dentry. */ @@ -379,19 +382,22 @@ if (IS_ERR(mrec)) return (struct dentry *)mrec; /* Find the first file name attribute in the mft record. */ - ctx = get_attr_search_ctx(ni, mrec); + ctx = ntfs_attr_get_search_ctx(ni, mrec); if (unlikely(!ctx)) { unmap_mft_record(ni); return ERR_PTR(-ENOMEM); } try_next: - if (unlikely(!lookup_attr(AT_FILE_NAME, NULL, 0, CASE_SENSITIVE, 0, - NULL, 0, ctx))) { - put_attr_search_ctx(ctx); + err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, CASE_SENSITIVE, 0, NULL, + 0, ctx); + if (unlikely(err)) { + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(ni); - ntfs_error(vi->i_sb, "Inode 0x%lx does not have a file name " - "attribute. Run chkdsk.", vi->i_ino); - return ERR_PTR(-ENOENT); + if (err == -ENOENT) + ntfs_error(vi->i_sb, "Inode 0x%lx does not have a " + "file name attribute. Run chkdsk.", + vi->i_ino); + return ERR_PTR(err); } attr = ctx->attr; if (unlikely(attr->non_resident)) @@ -404,7 +410,7 @@ /* Get the inode number of the parent directory. */ parent_ino = MREF_LE(fn->parent_directory); /* Release the search context and the mft record of the child. */ - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(ni); /* Get the inode of the parent directory. */ parent_vi = ntfs_iget(vi->i_sb, parent_ino); diff -Nru a/fs/ntfs/super.c b/fs/ntfs/super.c --- a/fs/ntfs/super.c 2004-09-21 21:06:35 -07:00 +++ b/fs/ntfs/super.c 2004-09-21 21:06:35 -07:00 @@ -29,6 +29,7 @@ #include #include #include +#include #include "ntfs.h" #include "sysctl.h" @@ -317,7 +318,7 @@ ntfs_inode *ni = NTFS_I(vol->vol_ino); MFT_RECORD *m; VOLUME_INFORMATION *vi; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; int err; ntfs_debug("Entering, old flags = 0x%x, new flags = 0x%x.", @@ -330,28 +331,28 @@ err = PTR_ERR(m); goto err_out; } - ctx = get_attr_search_ctx(ni, m); + ctx = ntfs_attr_get_search_ctx(ni, m); if (!ctx) { err = -ENOMEM; goto put_unm_err_out; } - if (!lookup_attr(AT_VOLUME_INFORMATION, NULL, 0, 0, 0, NULL, 0, ctx)) { - err = -EIO; + err = ntfs_attr_lookup(AT_VOLUME_INFORMATION, NULL, 0, 0, 0, NULL, 0, + ctx); + if (err) goto put_unm_err_out; - } vi = (VOLUME_INFORMATION*)((u8*)ctx->attr + le16_to_cpu(ctx->attr->data.resident.value_offset)); vol->vol_flags = vi->flags = flags; flush_dcache_mft_record_page(ctx->ntfs_ino); mark_mft_record_dirty(ctx->ntfs_ino); - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(ni); done: ntfs_debug("Done."); return 0; put_unm_err_out: if (ctx) - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(ni); err_out: ntfs_error(vol->sb, "Failed with error code %i.", -err); @@ -1343,7 +1344,7 @@ struct super_block *sb = vol->sb; MFT_RECORD *m; VOLUME_INFORMATION *vi; - attr_search_context *ctx; + ntfs_attr_search_ctx *ctx; ntfs_debug("Entering."); #ifdef NTFS_RW @@ -1427,14 +1428,14 @@ iput(vol->vol_ino); goto volume_failed; } - if (!(ctx = get_attr_search_ctx(NTFS_I(vol->vol_ino), m))) { + if (!(ctx = ntfs_attr_get_search_ctx(NTFS_I(vol->vol_ino), m))) { ntfs_error(sb, "Failed to get attribute search context."); goto get_ctx_vol_failed; } - if (!lookup_attr(AT_VOLUME_INFORMATION, NULL, 0, 0, 0, NULL, 0, ctx) || - ctx->attr->non_resident || ctx->attr->flags) { + if (ntfs_attr_lookup(AT_VOLUME_INFORMATION, NULL, 0, 0, 0, NULL, 0, + ctx) || ctx->attr->non_resident || ctx->attr->flags) { err_put_vol: - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); get_ctx_vol_failed: unmap_mft_record(NTFS_I(vol->vol_ino)); goto iput_volume_failed; @@ -1450,7 +1451,7 @@ vol->vol_flags = vi->flags; vol->major_ver = vi->major_ver; vol->minor_ver = vi->minor_ver; - put_attr_search_ctx(ctx); + ntfs_attr_put_search_ctx(ctx); unmap_mft_record(NTFS_I(vol->vol_ino)); printk(KERN_INFO "NTFS volume version %i.%i.\n", vol->major_ver, vol->minor_ver); @@ -2013,7 +2014,7 @@ */ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol) { - s64 nr_free = vol->nr_mft_records; + s64 nr_free; u32 *kaddr; struct address_space *mapping = vol->mftbmp_ino->i_mapping; filler_t *readpage = (filler_t*)mapping->a_ops->readpage; @@ -2022,13 +2023,16 @@ unsigned int max_size; ntfs_debug("Entering."); + /* Number of mft records in file system (at this point in time). */ + nr_free = vol->mft_ino->i_size >> vol->mft_record_size_bits; /* - * Convert the number of bits into bytes rounded up, then convert into - * multiples of PAGE_CACHE_SIZE, rounding up so that if we have one - * full and one partial page max_index = 2. - */ - max_index = (((vol->nr_mft_records + 7) >> 3) + PAGE_CACHE_SIZE - 1) >> - PAGE_CACHE_SHIFT; + * Convert the maximum number of set bits into bytes rounded up, then + * convert into multiples of PAGE_CACHE_SIZE, rounding up so that if we + * have one full and one partial page max_index = 2. + */ + max_index = ((((NTFS_I(vol->mft_ino)->initialized_size >> + vol->mft_record_size_bits) + 7) >> 3) + + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; /* Use multiples of 4 bytes. */ max_size = PAGE_CACHE_SIZE >> 2; ntfs_debug("Reading $MFT/$BITMAP, max_index = 0x%lx, max_size = " @@ -2123,9 +2127,9 @@ sfs->f_bavail = sfs->f_bfree = size; /* Serialize accesses to the inode bitmap. */ down_read(&vol->mftbmp_lock); - /* Total file nodes in file system (at this moment in time). */ - sfs->f_files = vol->mft_ino->i_size >> vol->mft_record_size_bits; - /* Free file nodes in fs (based on current total count). */ + /* Number of inodes in file system (at this point in time). */ + sfs->f_files = vol->mft_ino->i_size >> vol->mft_record_size_bits; + /* Free inodes in fs (based on current total count). */ sfs->f_ffree = __get_nr_free_mft_records(vol); up_read(&vol->mftbmp_lock); /* @@ -2288,6 +2292,8 @@ vol->fmask = 0177; vol->dmask = 0077; + unlock_kernel(); + /* Important to get the mount options dealt with now. */ if (!parse_options(vol, (char*)opt)) goto err_out_now; @@ -2424,6 +2430,7 @@ } up(&ntfs_lock); sb->s_export_op = &ntfs_export_ops; + lock_kernel(); return 0; } ntfs_error(sb, "Failed to allocate root directory."); @@ -2527,6 +2534,7 @@ } /* Errors at this stage are irrelevant. */ err_out_now: + lock_kernel(); sb->s_fs_info = NULL; kfree(vol); ntfs_debug("Failed, returning -EINVAL."); @@ -2620,7 +2628,7 @@ goto ictx_err_out; } ntfs_attr_ctx_cache = kmem_cache_create(ntfs_attr_ctx_cache_name, - sizeof(attr_search_context), 0 /* offset */, + sizeof(ntfs_attr_search_ctx), 0 /* offset */, SLAB_HWCACHE_ALIGN, NULL /* ctor */, NULL /* dtor */); if (!ntfs_attr_ctx_cache) { printk(KERN_CRIT "NTFS: Failed to create %s!\n", diff -Nru a/fs/ntfs/volume.h b/fs/ntfs/volume.h --- a/fs/ntfs/volume.h 2004-09-21 21:06:35 -07:00 +++ b/fs/ntfs/volume.h 2004-09-21 21:06:35 -07:00 @@ -95,9 +95,6 @@ struct inode *mftbmp_ino; /* Attribute inode for $MFT/$BITMAP. */ struct rw_semaphore mftbmp_lock; /* Lock for serializing accesses to the mft record bitmap ($MFT/$BITMAP). */ - unsigned long nr_mft_records; /* Number of mft records == number of - bits in mft bitmap. */ - #ifdef NTFS_RW struct inode *mftmirr_ino; /* The VFS inode of $MFTMirr. */ int mftmirr_size; /* Size of mft mirror in mft records. */