Commit c8cdf479377462315d6b4f56379f8ac989b0ef29

Authored by Steven Whitehouse
1 parent b35997d448

[GFS2] Recovery for lost unlinked inodes

Under certain circumstances its possible (though rather unlikely) that
inodes which were unlinked by one node while still open on another might
get "lost" in the sense that they don't get deallocated if the node
which held the inode open crashed before it was unlinked.

This patch adds the recovery code which allows automatic deallocation of
the inode if its found during block allocation (the sensible time to
look for such inodes since we are scanning the rgrp's bitmaps anyway at
this time, so it adds no overhead to do this).

Since the inode will have had its i_nlink set to zero, all we need to
trigger recovery is a lookup and an iput(), and the normal deallocation
code takes care of the rest.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

Showing 3 changed files with 107 additions and 32 deletions Side-by-side Diff

... ... @@ -95,6 +95,8 @@
95 95 u32 rd_last_alloc_data;
96 96 u32 rd_last_alloc_meta;
97 97 struct gfs2_sbd *rd_sbd;
  98 + unsigned long rd_flags;
  99 +#define GFS2_RDF_CHECK 0x0001 /* Need to check for unlinked inodes */
98 100 };
99 101  
100 102 enum gfs2_state_bits {
... ... @@ -98,23 +98,9 @@
98 98  
99 99 if (inode->i_state & I_NEW) {
100 100 struct gfs2_sbd *sdp = GFS2_SB(inode);
101   - umode_t mode = DT2IF(type);
  101 + umode_t mode;
102 102 inode->i_private = ip;
103   - inode->i_mode = mode;
104 103  
105   - if (S_ISREG(mode)) {
106   - inode->i_op = &gfs2_file_iops;
107   - inode->i_fop = &gfs2_file_fops;
108   - inode->i_mapping->a_ops = &gfs2_file_aops;
109   - } else if (S_ISDIR(mode)) {
110   - inode->i_op = &gfs2_dir_iops;
111   - inode->i_fop = &gfs2_dir_fops;
112   - } else if (S_ISLNK(mode)) {
113   - inode->i_op = &gfs2_symlink_iops;
114   - } else {
115   - inode->i_op = &gfs2_dev_iops;
116   - }
117   -
118 104 error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
119 105 if (unlikely(error))
120 106 goto fail;
121 107  
... ... @@ -130,10 +116,44 @@
130 116 goto fail_iopen;
131 117  
132 118 gfs2_glock_put(io_gl);
  119 +
  120 + /*
  121 + * We must read the inode in order to work out its type in
  122 + * this case. Note that this doesn't happen often as we normally
  123 + * know the type beforehand. This code path only occurs during
  124 + * unlinked inode recovery (where it is safe to do this glock,
  125 + * which is not true in the general case).
  126 + */
  127 + inode->i_mode = mode = DT2IF(type);
  128 + if (type == DT_UNKNOWN) {
  129 + struct gfs2_holder gh;
  130 + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
  131 + if (unlikely(error))
  132 + goto fail_glock;
  133 + /* Inode is now uptodate */
  134 + mode = inode->i_mode;
  135 + gfs2_glock_dq_uninit(&gh);
  136 + }
  137 +
  138 + if (S_ISREG(mode)) {
  139 + inode->i_op = &gfs2_file_iops;
  140 + inode->i_fop = &gfs2_file_fops;
  141 + inode->i_mapping->a_ops = &gfs2_file_aops;
  142 + } else if (S_ISDIR(mode)) {
  143 + inode->i_op = &gfs2_dir_iops;
  144 + inode->i_fop = &gfs2_dir_fops;
  145 + } else if (S_ISLNK(mode)) {
  146 + inode->i_op = &gfs2_symlink_iops;
  147 + } else {
  148 + inode->i_op = &gfs2_dev_iops;
  149 + }
  150 +
133 151 unlock_new_inode(inode);
134 152 }
135 153  
136 154 return inode;
  155 +fail_glock:
  156 + gfs2_glock_dq(&ip->i_iopen_gh);
137 157 fail_iopen:
138 158 gfs2_glock_put(io_gl);
139 159 fail_put:
No preview for this file type