summaryrefslogtreecommitdiffstats
path: root/fs/udf/inode.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2014-10-09 12:52:16 +0200
committerJan Kara <jack@suse.cz>2014-10-09 13:06:14 +0200
commit6174c2eb8ecef271159bdcde460ce8af54d8f72f (patch)
treefc00824fdd8231ac9ee32714fc86493149af29d1 /fs/udf/inode.c
parentc53f755d339b5546600c316333140d5fe958941d (diff)
downloadlinux-0-day-6174c2eb8ecef271159bdcde460ce8af54d8f72f.tar.gz
linux-0-day-6174c2eb8ecef271159bdcde460ce8af54d8f72f.tar.xz
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.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 08598843288fe..c9b4df5810d52 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);