diff options
author | Jan Kara <jack@suse.cz> | 2014-10-09 12:52:16 +0200 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2014-10-09 13:06:14 +0200 |
commit | 6174c2eb8ecef271159bdcde460ce8af54d8f72f (patch) | |
tree | fc00824fdd8231ac9ee32714fc86493149af29d1 /fs/udf/inode.c | |
parent | c53f755d339b5546600c316333140d5fe958941d (diff) | |
download | linux-6174c2eb8ecef271159bdcde460ce8af54d8f72f.tar.bz2 |
udf: Fix loading of special inodes
Some UDF media have special inodes (like VAT or metadata partition
inodes) whose link_count is 0. Thus commit 4071b9136223 (udf: Properly
detect stale inodes) broke loading these inodes because udf_iget()
started returning -ESTALE for them. Since we still need to properly
detect stale inodes queried by NFS, create two variants of udf_iget() -
one which is used for looking up special inodes (which ignores
link_count == 0) and one which is used for other cases which return
ESTALE when link_count == 0.
Fixes: 4071b913622316970d0e1919f7d82b4403fec5f2
CC: stable@vger.kernel.org
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf/inode.c')
-rw-r--r-- | fs/udf/inode.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 08598843288f..c9b4df5810d5 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1277,7 +1277,7 @@ update_time: */ #define UDF_MAX_ICB_NESTING 1024 -static int udf_read_inode(struct inode *inode) +static int udf_read_inode(struct inode *inode, bool hidden_inode) { struct buffer_head *bh = NULL; struct fileEntry *fe; @@ -1436,8 +1436,11 @@ reread: link_count = le16_to_cpu(fe->fileLinkCount); if (!link_count) { - ret = -ESTALE; - goto out; + if (!hidden_inode) { + ret = -ESTALE; + goto out; + } + link_count = 1; } set_nlink(inode, link_count); @@ -1826,7 +1829,8 @@ out: return err; } -struct inode *udf_iget(struct super_block *sb, struct kernel_lb_addr *ino) +struct inode *__udf_iget(struct super_block *sb, struct kernel_lb_addr *ino, + bool hidden_inode) { unsigned long block = udf_get_lb_pblock(sb, ino, 0); struct inode *inode = iget_locked(sb, block); @@ -1839,7 +1843,7 @@ struct inode *udf_iget(struct super_block *sb, struct kernel_lb_addr *ino) return inode; memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr)); - err = udf_read_inode(inode); + err = udf_read_inode(inode, hidden_inode); if (err < 0) { iget_failed(inode); return ERR_PTR(err); |