summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@openedhand.com>2008-09-10 15:37:14 +0000
committerSamuel Ortiz <sameo@openedhand.com>2008-09-10 15:37:14 +0000
commit4f82c5078e46fa0799038df33ad1cd624cf54bde (patch)
tree0f7015a79d98b8469116903261390b91c9b5cef3
parentf680c855cf7dd3a3481a28671bdf918dbfb551df (diff)
downloadpoky-4f82c5078e46fa0799038df33ad1cd624cf54bde.tar.gz
linux-moblin2: Add moblin2 kernel
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@5166 311d38ba-8fff-0310-9ca6-ca027cbcb966
-rw-r--r--meta/packages/linux/linux-moblin2-2.6.27-rc1/0001_Export_shmem_file_setup_for_DRM-GEM.patch27
-rw-r--r--meta/packages/linux/linux-moblin2-2.6.27-rc1/0002_i915.Use_more_consistent_names_for_regs.patch2739
-rw-r--r--meta/packages/linux/linux-moblin2-2.6.27-rc1/0003_i915.Add_support_for_MSI_and_interrupt_mitigation.patch421
-rw-r--r--meta/packages/linux/linux-moblin2-2.6.27-rc1/0004_i915.Track_progress_inside_of_batchbuffers_for_determining_wedgedness.patch47
-rw-r--r--meta/packages/linux/linux-moblin2-2.6.27-rc1/0005_i915.remove_settable_use_mi_batchbuffer_start.patch59
-rw-r--r--meta/packages/linux/linux-moblin2-2.6.27-rc1/0006_i915.Ignore_X_server_provided_mmio_address.patch42
-rw-r--r--meta/packages/linux/linux-moblin2-2.6.27-rc1/0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch138
-rw-r--r--meta/packages/linux/linux-moblin2-2.6.27-rc1/0008_drm.Add_GEM_graphics_execution_manager_to_i915_driver.patch5453
-rw-r--r--meta/packages/linux/linux-moblin2-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch6727
-rw-r--r--meta/packages/linux/linux-moblin2-2.6.27-rc1/0010_unionfs-2.4_for_2.6.27-rc1.patch11320
-rw-r--r--meta/packages/linux/linux-moblin2-2.6.27-rc1/0011_workaround_unidef_step.patch10
-rw-r--r--meta/packages/linux/linux-moblin2-2.6.27-rc1/0012_intelfb_945gme.patch153
-rw-r--r--meta/packages/linux/linux-moblin2-2.6.27-rc1/defconfig-eee9012322
-rw-r--r--meta/packages/linux/linux-moblin2.inc18
-rw-r--r--meta/packages/linux/linux-moblin2_2.6.27-rc1.bb23
15 files changed, 29499 insertions, 0 deletions
diff --git a/meta/packages/linux/linux-moblin2-2.6.27-rc1/0001_Export_shmem_file_setup_for_DRM-GEM.patch b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0001_Export_shmem_file_setup_for_DRM-GEM.patch
new file mode 100644
index 0000000000..9589838afa
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0001_Export_shmem_file_setup_for_DRM-GEM.patch
@@ -0,0 +1,27 @@
1From: Keith Packard <keithp@keithp.com>
2Date: Fri, 20 Jun 2008 07:08:06 +0000 (-0700)
3Subject: Export shmem_file_setup for DRM-GEM
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=350ea3ece12744ae154bbc2ea13da6ba84ca5515
6
7Export shmem_file_setup for DRM-GEM
8
9GEM needs to create shmem files to back buffer objects. Though currently
10creation of files for objects could have been driven from userland, the
11modesetting work will require allocation of buffer objects before userland
12is running, for boot-time message display.
13
14Signed-off-by: Eric Anholt <eric@anholt.net>
15---
16
17--- a/mm/shmem.c
18+++ b/mm/shmem.c
19@@ -2582,6 +2582,7 @@ put_memory:
20 shmem_unacct_size(flags, size);
21 return ERR_PTR(error);
22 }
23+EXPORT_SYMBOL(shmem_file_setup);
24
25 /**
26 * shmem_zero_setup - setup a shared anonymous mapping
27
diff --git a/meta/packages/linux/linux-moblin2-2.6.27-rc1/0002_i915.Use_more_consistent_names_for_regs.patch b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0002_i915.Use_more_consistent_names_for_regs.patch
new file mode 100644
index 0000000000..9a035b544c
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0002_i915.Use_more_consistent_names_for_regs.patch
@@ -0,0 +1,2739 @@
1From: Jesse Barnes <jbarnes@virtuousgeek.org>
2Date: Tue, 29 Jul 2008 18:54:06 +0000 (-0700)
3Subject: i915: Use more consistent names for regs, and store them in a separate file.
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=db1cbbd8c4d42e58e9acb3e7af59ad1bb238260d
6
7i915: Use more consistent names for regs, and store them in a separate file.
8
9Signed-off-by: Eric Anholt <eric@anholt.net>
10---
11
12--- a/drivers/gpu/drm/i915/i915_dma.c
13+++ b/drivers/gpu/drm/i915/i915_dma.c
14@@ -40,11 +40,11 @@ int i915_wait_ring(struct drm_device * d
15 {
16 drm_i915_private_t *dev_priv = dev->dev_private;
17 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
18- u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
19+ u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
20 int i;
21
22 for (i = 0; i < 10000; i++) {
23- ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
24+ ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
25 ring->space = ring->head - (ring->tail + 8);
26 if (ring->space < 0)
27 ring->space += ring->Size;
28@@ -67,8 +67,8 @@ void i915_kernel_lost_context(struct drm
29 drm_i915_private_t *dev_priv = dev->dev_private;
30 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
31
32- ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
33- ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
34+ ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
35+ ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
36 ring->space = ring->head - (ring->tail + 8);
37 if (ring->space < 0)
38 ring->space += ring->Size;
39@@ -98,13 +98,13 @@ static int i915_dma_cleanup(struct drm_d
40 drm_pci_free(dev, dev_priv->status_page_dmah);
41 dev_priv->status_page_dmah = NULL;
42 /* Need to rewrite hardware status page */
43- I915_WRITE(0x02080, 0x1ffff000);
44+ I915_WRITE(HWS_PGA, 0x1ffff000);
45 }
46
47 if (dev_priv->status_gfx_addr) {
48 dev_priv->status_gfx_addr = 0;
49 drm_core_ioremapfree(&dev_priv->hws_map, dev);
50- I915_WRITE(0x2080, 0x1ffff000);
51+ I915_WRITE(HWS_PGA, 0x1ffff000);
52 }
53
54 return 0;
55@@ -170,7 +170,7 @@ static int i915_initialize(struct drm_de
56 dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
57
58 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
59- I915_WRITE(0x02080, dev_priv->dma_status_page);
60+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
61 }
62 DRM_DEBUG("Enabled hardware status page\n");
63 return 0;
64@@ -201,9 +201,9 @@ static int i915_dma_resume(struct drm_de
65 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
66
67 if (dev_priv->status_gfx_addr != 0)
68- I915_WRITE(0x02080, dev_priv->status_gfx_addr);
69+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
70 else
71- I915_WRITE(0x02080, dev_priv->dma_status_page);
72+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
73 DRM_DEBUG("Enabled hardware status page\n");
74
75 return 0;
76@@ -402,8 +402,8 @@ static void i915_emit_breadcrumb(struct
77 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
78
79 BEGIN_LP_RING(4);
80- OUT_RING(CMD_STORE_DWORD_IDX);
81- OUT_RING(20);
82+ OUT_RING(MI_STORE_DWORD_INDEX);
83+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
84 OUT_RING(dev_priv->counter);
85 OUT_RING(0);
86 ADVANCE_LP_RING();
87@@ -505,7 +505,7 @@ static int i915_dispatch_flip(struct drm
88 i915_kernel_lost_context(dev);
89
90 BEGIN_LP_RING(2);
91- OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
92+ OUT_RING(MI_FLUSH | MI_READ_FLUSH);
93 OUT_RING(0);
94 ADVANCE_LP_RING();
95
96@@ -530,8 +530,8 @@ static int i915_dispatch_flip(struct drm
97 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++;
98
99 BEGIN_LP_RING(4);
100- OUT_RING(CMD_STORE_DWORD_IDX);
101- OUT_RING(20);
102+ OUT_RING(MI_STORE_DWORD_INDEX);
103+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
104 OUT_RING(dev_priv->counter);
105 OUT_RING(0);
106 ADVANCE_LP_RING();
107@@ -728,8 +728,8 @@ static int i915_set_status_page(struct d
108 dev_priv->hw_status_page = dev_priv->hws_map.handle;
109
110 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
111- I915_WRITE(0x02080, dev_priv->status_gfx_addr);
112- DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n",
113+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
114+ DRM_DEBUG("load hws HWS_PGA with gfx mem 0x%x\n",
115 dev_priv->status_gfx_addr);
116 DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
117 return 0;
118--- a/drivers/gpu/drm/i915/i915_drv.c
119+++ b/drivers/gpu/drm/i915/i915_drv.c
120@@ -279,13 +279,13 @@ static int i915_suspend(struct drm_devic
121 dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
122 dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
123 dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
124- dev_priv->saveDSPABASE = I915_READ(DSPABASE);
125+ dev_priv->saveDSPAADDR = I915_READ(DSPAADDR);
126 if (IS_I965G(dev)) {
127 dev_priv->saveDSPASURF = I915_READ(DSPASURF);
128 dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
129 }
130 i915_save_palette(dev, PIPE_A);
131- dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT);
132+ dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT);
133
134 /* Pipe & plane B info */
135 dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
136@@ -307,13 +307,13 @@ static int i915_suspend(struct drm_devic
137 dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
138 dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
139 dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
140- dev_priv->saveDSPBBASE = I915_READ(DSPBBASE);
141+ dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
142 if (IS_I965GM(dev) || IS_IGD_GM(dev)) {
143 dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
144 dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
145 }
146 i915_save_palette(dev, PIPE_B);
147- dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT);
148+ dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
149
150 /* CRT state */
151 dev_priv->saveADPA = I915_READ(ADPA);
152@@ -328,9 +328,9 @@ static int i915_suspend(struct drm_devic
153 dev_priv->saveLVDS = I915_READ(LVDS);
154 if (!IS_I830(dev) && !IS_845G(dev))
155 dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
156- dev_priv->saveLVDSPP_ON = I915_READ(LVDSPP_ON);
157- dev_priv->saveLVDSPP_OFF = I915_READ(LVDSPP_OFF);
158- dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE);
159+ dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
160+ dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
161+ dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
162
163 /* FIXME: save TV & SDVO state */
164
165@@ -341,19 +341,19 @@ static int i915_suspend(struct drm_devic
166 dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
167
168 /* Interrupt state */
169- dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R);
170- dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R);
171- dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R);
172+ dev_priv->saveIIR = I915_READ(IIR);
173+ dev_priv->saveIER = I915_READ(IER);
174+ dev_priv->saveIMR = I915_READ(IMR);
175
176 /* VGA state */
177- dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0);
178- dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1);
179- dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV);
180+ dev_priv->saveVGA0 = I915_READ(VGA0);
181+ dev_priv->saveVGA1 = I915_READ(VGA1);
182+ dev_priv->saveVGA_PD = I915_READ(VGA_PD);
183 dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
184
185 /* Clock gating state */
186 dev_priv->saveD_STATE = I915_READ(D_STATE);
187- dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
188+ dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
189
190 /* Cache mode state */
191 dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
192@@ -363,7 +363,7 @@ static int i915_suspend(struct drm_devic
193
194 /* Scratch space */
195 for (i = 0; i < 16; i++) {
196- dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2));
197+ dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2));
198 dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
199 }
200 for (i = 0; i < 3; i++)
201@@ -424,7 +424,7 @@ static int i915_resume(struct drm_device
202 I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
203 I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
204 I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
205- I915_WRITE(DSPABASE, dev_priv->saveDSPABASE);
206+ I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR);
207 I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
208 if (IS_I965G(dev)) {
209 I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
210@@ -436,7 +436,7 @@ static int i915_resume(struct drm_device
211 i915_restore_palette(dev, PIPE_A);
212 /* Enable the plane */
213 I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
214- I915_WRITE(DSPABASE, I915_READ(DSPABASE));
215+ I915_WRITE(DSPAADDR, I915_READ(DSPAADDR));
216
217 /* Pipe & plane B info */
218 if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
219@@ -466,7 +466,7 @@ static int i915_resume(struct drm_device
220 I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
221 I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
222 I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
223- I915_WRITE(DSPBBASE, dev_priv->saveDSPBBASE);
224+ I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR);
225 I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
226 if (IS_I965G(dev)) {
227 I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
228@@ -478,7 +478,7 @@ static int i915_resume(struct drm_device
229 i915_restore_palette(dev, PIPE_B);
230 /* Enable the plane */
231 I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
232- I915_WRITE(DSPBBASE, I915_READ(DSPBBASE));
233+ I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
234
235 /* CRT state */
236 I915_WRITE(ADPA, dev_priv->saveADPA);
237@@ -493,9 +493,9 @@ static int i915_resume(struct drm_device
238
239 I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
240 I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
241- I915_WRITE(LVDSPP_ON, dev_priv->saveLVDSPP_ON);
242- I915_WRITE(LVDSPP_OFF, dev_priv->saveLVDSPP_OFF);
243- I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE);
244+ I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
245+ I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
246+ I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
247 I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
248
249 /* FIXME: restore TV & SDVO state */
250@@ -508,14 +508,14 @@ static int i915_resume(struct drm_device
251
252 /* VGA state */
253 I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
254- I915_WRITE(VCLK_DIVISOR_VGA0, dev_priv->saveVCLK_DIVISOR_VGA0);
255- I915_WRITE(VCLK_DIVISOR_VGA1, dev_priv->saveVCLK_DIVISOR_VGA1);
256- I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV);
257+ I915_WRITE(VGA0, dev_priv->saveVGA0);
258+ I915_WRITE(VGA1, dev_priv->saveVGA1);
259+ I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
260 udelay(150);
261
262 /* Clock gating state */
263 I915_WRITE (D_STATE, dev_priv->saveD_STATE);
264- I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
265+ I915_WRITE(CG_2D_DIS, dev_priv->saveCG_2D_DIS);
266
267 /* Cache mode state */
268 I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
269@@ -524,7 +524,7 @@ static int i915_resume(struct drm_device
270 I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
271
272 for (i = 0; i < 16; i++) {
273- I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]);
274+ I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
275 I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
276 }
277 for (i = 0; i < 3; i++)
278--- a/drivers/gpu/drm/i915/i915_drv.h
279+++ b/drivers/gpu/drm/i915/i915_drv.h
280@@ -30,6 +30,8 @@
281 #ifndef _I915_DRV_H_
282 #define _I915_DRV_H_
283
284+#include "i915_reg.h"
285+
286 /* General customization:
287 */
288
289@@ -138,7 +140,7 @@ typedef struct drm_i915_private {
290 u32 saveDSPASTRIDE;
291 u32 saveDSPASIZE;
292 u32 saveDSPAPOS;
293- u32 saveDSPABASE;
294+ u32 saveDSPAADDR;
295 u32 saveDSPASURF;
296 u32 saveDSPATILEOFF;
297 u32 savePFIT_PGM_RATIOS;
298@@ -159,24 +161,24 @@ typedef struct drm_i915_private {
299 u32 saveDSPBSTRIDE;
300 u32 saveDSPBSIZE;
301 u32 saveDSPBPOS;
302- u32 saveDSPBBASE;
303+ u32 saveDSPBADDR;
304 u32 saveDSPBSURF;
305 u32 saveDSPBTILEOFF;
306- u32 saveVCLK_DIVISOR_VGA0;
307- u32 saveVCLK_DIVISOR_VGA1;
308- u32 saveVCLK_POST_DIV;
309+ u32 saveVGA0;
310+ u32 saveVGA1;
311+ u32 saveVGA_PD;
312 u32 saveVGACNTRL;
313 u32 saveADPA;
314 u32 saveLVDS;
315- u32 saveLVDSPP_ON;
316- u32 saveLVDSPP_OFF;
317+ u32 savePP_ON_DELAYS;
318+ u32 savePP_OFF_DELAYS;
319 u32 saveDVOA;
320 u32 saveDVOB;
321 u32 saveDVOC;
322 u32 savePP_ON;
323 u32 savePP_OFF;
324 u32 savePP_CONTROL;
325- u32 savePP_CYCLE;
326+ u32 savePP_DIVISOR;
327 u32 savePFIT_CONTROL;
328 u32 save_palette_a[256];
329 u32 save_palette_b[256];
330@@ -189,7 +191,7 @@ typedef struct drm_i915_private {
331 u32 saveIMR;
332 u32 saveCACHE_MODE_0;
333 u32 saveD_STATE;
334- u32 saveDSPCLK_GATE_D;
335+ u32 saveCG_2D_DIS;
336 u32 saveMI_ARB_STATE;
337 u32 saveSWF0[16];
338 u32 saveSWF1[16];
339@@ -283,816 +285,26 @@ extern void i915_mem_release(struct drm_
340 if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \
341 dev_priv->ring.tail = outring; \
342 dev_priv->ring.space -= outcount * 4; \
343- I915_WRITE(LP_RING + RING_TAIL, outring); \
344+ I915_WRITE(PRB0_TAIL, outring); \
345 } while(0)
346
347-extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
348-
349-/* Extended config space */
350-#define LBB 0xf4
351-
352-/* VGA stuff */
353-
354-#define VGA_ST01_MDA 0x3ba
355-#define VGA_ST01_CGA 0x3da
356-
357-#define VGA_MSR_WRITE 0x3c2
358-#define VGA_MSR_READ 0x3cc
359-#define VGA_MSR_MEM_EN (1<<1)
360-#define VGA_MSR_CGA_MODE (1<<0)
361-
362-#define VGA_SR_INDEX 0x3c4
363-#define VGA_SR_DATA 0x3c5
364-
365-#define VGA_AR_INDEX 0x3c0
366-#define VGA_AR_VID_EN (1<<5)
367-#define VGA_AR_DATA_WRITE 0x3c0
368-#define VGA_AR_DATA_READ 0x3c1
369-
370-#define VGA_GR_INDEX 0x3ce
371-#define VGA_GR_DATA 0x3cf
372-/* GR05 */
373-#define VGA_GR_MEM_READ_MODE_SHIFT 3
374-#define VGA_GR_MEM_READ_MODE_PLANE 1
375-/* GR06 */
376-#define VGA_GR_MEM_MODE_MASK 0xc
377-#define VGA_GR_MEM_MODE_SHIFT 2
378-#define VGA_GR_MEM_A0000_AFFFF 0
379-#define VGA_GR_MEM_A0000_BFFFF 1
380-#define VGA_GR_MEM_B0000_B7FFF 2
381-#define VGA_GR_MEM_B0000_BFFFF 3
382-
383-#define VGA_DACMASK 0x3c6
384-#define VGA_DACRX 0x3c7
385-#define VGA_DACWX 0x3c8
386-#define VGA_DACDATA 0x3c9
387-
388-#define VGA_CR_INDEX_MDA 0x3b4
389-#define VGA_CR_DATA_MDA 0x3b5
390-#define VGA_CR_INDEX_CGA 0x3d4
391-#define VGA_CR_DATA_CGA 0x3d5
392-
393-#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
394-#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
395-#define CMD_REPORT_HEAD (7<<23)
396-#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
397-#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
398-
399-#define INST_PARSER_CLIENT 0x00000000
400-#define INST_OP_FLUSH 0x02000000
401-#define INST_FLUSH_MAP_CACHE 0x00000001
402-
403-#define BB1_START_ADDR_MASK (~0x7)
404-#define BB1_PROTECTED (1<<0)
405-#define BB1_UNPROTECTED (0<<0)
406-#define BB2_END_ADDR_MASK (~0x7)
407-
408-/* Framebuffer compression */
409-#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
410-#define FBC_LL_BASE 0x03204 /* 4k page aligned */
411-#define FBC_CONTROL 0x03208
412-#define FBC_CTL_EN (1<<31)
413-#define FBC_CTL_PERIODIC (1<<30)
414-#define FBC_CTL_INTERVAL_SHIFT (16)
415-#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
416-#define FBC_CTL_STRIDE_SHIFT (5)
417-#define FBC_CTL_FENCENO (1<<0)
418-#define FBC_COMMAND 0x0320c
419-#define FBC_CMD_COMPRESS (1<<0)
420-#define FBC_STATUS 0x03210
421-#define FBC_STAT_COMPRESSING (1<<31)
422-#define FBC_STAT_COMPRESSED (1<<30)
423-#define FBC_STAT_MODIFIED (1<<29)
424-#define FBC_STAT_CURRENT_LINE (1<<0)
425-#define FBC_CONTROL2 0x03214
426-#define FBC_CTL_FENCE_DBL (0<<4)
427-#define FBC_CTL_IDLE_IMM (0<<2)
428-#define FBC_CTL_IDLE_FULL (1<<2)
429-#define FBC_CTL_IDLE_LINE (2<<2)
430-#define FBC_CTL_IDLE_DEBUG (3<<2)
431-#define FBC_CTL_CPU_FENCE (1<<1)
432-#define FBC_CTL_PLANEA (0<<0)
433-#define FBC_CTL_PLANEB (1<<0)
434-#define FBC_FENCE_OFF 0x0321b
435-
436-#define FBC_LL_SIZE (1536)
437-#define FBC_LL_PAD (32)
438-
439-/* Interrupt bits:
440- */
441-#define USER_INT_FLAG (1<<1)
442-#define VSYNC_PIPEB_FLAG (1<<5)
443-#define VSYNC_PIPEA_FLAG (1<<7)
444-#define HWB_OOM_FLAG (1<<13) /* binner out of memory */
445-
446-#define I915REG_HWSTAM 0x02098
447-#define I915REG_INT_IDENTITY_R 0x020a4
448-#define I915REG_INT_MASK_R 0x020a8
449-#define I915REG_INT_ENABLE_R 0x020a0
450-
451-#define I915REG_PIPEASTAT 0x70024
452-#define I915REG_PIPEBSTAT 0x71024
453-
454-#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
455-#define I915_VBLANK_CLEAR (1UL<<1)
456-
457-#define SRX_INDEX 0x3c4
458-#define SRX_DATA 0x3c5
459-#define SR01 1
460-#define SR01_SCREEN_OFF (1<<5)
461-
462-#define PPCR 0x61204
463-#define PPCR_ON (1<<0)
464-
465-#define DVOB 0x61140
466-#define DVOB_ON (1<<31)
467-#define DVOC 0x61160
468-#define DVOC_ON (1<<31)
469-#define LVDS 0x61180
470-#define LVDS_ON (1<<31)
471-
472-#define ADPA 0x61100
473-#define ADPA_DPMS_MASK (~(3<<10))
474-#define ADPA_DPMS_ON (0<<10)
475-#define ADPA_DPMS_SUSPEND (1<<10)
476-#define ADPA_DPMS_STANDBY (2<<10)
477-#define ADPA_DPMS_OFF (3<<10)
478-
479-#define NOPID 0x2094
480-#define LP_RING 0x2030
481-#define HP_RING 0x2040
482-/* The binner has its own ring buffer:
483- */
484-#define HWB_RING 0x2400
485-
486-#define RING_TAIL 0x00
487-#define TAIL_ADDR 0x001FFFF8
488-#define RING_HEAD 0x04
489-#define HEAD_WRAP_COUNT 0xFFE00000
490-#define HEAD_WRAP_ONE 0x00200000
491-#define HEAD_ADDR 0x001FFFFC
492-#define RING_START 0x08
493-#define START_ADDR 0x0xFFFFF000
494-#define RING_LEN 0x0C
495-#define RING_NR_PAGES 0x001FF000
496-#define RING_REPORT_MASK 0x00000006
497-#define RING_REPORT_64K 0x00000002
498-#define RING_REPORT_128K 0x00000004
499-#define RING_NO_REPORT 0x00000000
500-#define RING_VALID_MASK 0x00000001
501-#define RING_VALID 0x00000001
502-#define RING_INVALID 0x00000000
503-
504-/* Instruction parser error reg:
505- */
506-#define IPEIR 0x2088
507-
508-/* Scratch pad debug 0 reg:
509- */
510-#define SCPD0 0x209c
511-
512-/* Error status reg:
513- */
514-#define ESR 0x20b8
515-
516-/* Secondary DMA fetch address debug reg:
517- */
518-#define DMA_FADD_S 0x20d4
519-
520-/* Memory Interface Arbitration State
521- */
522-#define MI_ARB_STATE 0x20e4
523-
524-/* Cache mode 0 reg.
525- * - Manipulating render cache behaviour is central
526- * to the concept of zone rendering, tuning this reg can help avoid
527- * unnecessary render cache reads and even writes (for z/stencil)
528- * at beginning and end of scene.
529- *
530- * - To change a bit, write to this reg with a mask bit set and the
531- * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set.
532- */
533-#define Cache_Mode_0 0x2120
534-#define CACHE_MODE_0 0x2120
535-#define CM0_MASK_SHIFT 16
536-#define CM0_IZ_OPT_DISABLE (1<<6)
537-#define CM0_ZR_OPT_DISABLE (1<<5)
538-#define CM0_DEPTH_EVICT_DISABLE (1<<4)
539-#define CM0_COLOR_EVICT_DISABLE (1<<3)
540-#define CM0_DEPTH_WRITE_DISABLE (1<<1)
541-#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
542-
543-
544-/* Graphics flush control. A CPU write flushes the GWB of all writes.
545- * The data is discarded.
546- */
547-#define GFX_FLSH_CNTL 0x2170
548-
549-/* Binner control. Defines the location of the bin pointer list:
550- */
551-#define BINCTL 0x2420
552-#define BC_MASK (1 << 9)
553-
554-/* Binned scene info.
555- */
556-#define BINSCENE 0x2428
557-#define BS_OP_LOAD (1 << 8)
558-#define BS_MASK (1 << 22)
559-
560-/* Bin command parser debug reg:
561- */
562-#define BCPD 0x2480
563-
564-/* Bin memory control debug reg:
565- */
566-#define BMCD 0x2484
567-
568-/* Bin data cache debug reg:
569- */
570-#define BDCD 0x2488
571-
572-/* Binner pointer cache debug reg:
573- */
574-#define BPCD 0x248c
575-
576-/* Binner scratch pad debug reg:
577- */
578-#define BINSKPD 0x24f0
579-
580-/* HWB scratch pad debug reg:
581- */
582-#define HWBSKPD 0x24f4
583-
584-/* Binner memory pool reg:
585- */
586-#define BMP_BUFFER 0x2430
587-#define BMP_PAGE_SIZE_4K (0 << 10)
588-#define BMP_BUFFER_SIZE_SHIFT 1
589-#define BMP_ENABLE (1 << 0)
590-
591-/* Get/put memory from the binner memory pool:
592- */
593-#define BMP_GET 0x2438
594-#define BMP_PUT 0x2440
595-#define BMP_OFFSET_SHIFT 5
596-
597-/* 3D state packets:
598- */
599-#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
600-
601-#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
602-#define SC_UPDATE_SCISSOR (0x1<<1)
603-#define SC_ENABLE_MASK (0x1<<0)
604-#define SC_ENABLE (0x1<<0)
605-
606-#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
607-
608-#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
609-#define SCI_YMIN_MASK (0xffff<<16)
610-#define SCI_XMIN_MASK (0xffff<<0)
611-#define SCI_YMAX_MASK (0xffff<<16)
612-#define SCI_XMAX_MASK (0xffff<<0)
613-
614-#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
615-#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
616-#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
617-#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
618-#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
619-#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
620-#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
621-
622-#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
623-
624-#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
625-#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
626-#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
627-#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
628-#define XY_SRC_COPY_BLT_SRC_TILED (1<<15)
629-#define XY_SRC_COPY_BLT_DST_TILED (1<<11)
630-
631-#define MI_BATCH_BUFFER ((0x30<<23)|1)
632-#define MI_BATCH_BUFFER_START (0x31<<23)
633-#define MI_BATCH_BUFFER_END (0xA<<23)
634-#define MI_BATCH_NON_SECURE (1)
635-#define MI_BATCH_NON_SECURE_I965 (1<<8)
636-
637-#define MI_WAIT_FOR_EVENT ((0x3<<23))
638-#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
639-#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
640-#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
641-
642-#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23))
643-
644-#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
645-#define ASYNC_FLIP (1<<22)
646-#define DISPLAY_PLANE_A (0<<20)
647-#define DISPLAY_PLANE_B (1<<20)
648-
649-/* Display regs */
650-#define DSPACNTR 0x70180
651-#define DSPBCNTR 0x71180
652-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
653-
654-/* Define the region of interest for the binner:
655- */
656-#define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4)
657-
658-#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
659-
660-#define CMD_MI_FLUSH (0x04 << 23)
661-#define MI_NO_WRITE_FLUSH (1 << 2)
662-#define MI_READ_FLUSH (1 << 0)
663-#define MI_EXE_FLUSH (1 << 1)
664-#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
665-#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
666-
667-#define BREADCRUMB_BITS 31
668-#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
669-
670-#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5])
671-#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
672-
673-#define BLC_PWM_CTL 0x61254
674-#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
675-
676-#define BLC_PWM_CTL2 0x61250
677 /**
678- * This is the most significant 15 bits of the number of backlight cycles in a
679- * complete cycle of the modulated backlight control.
680+ * Reads a dword out of the status page, which is written to from the command
681+ * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or
682+ * MI_STORE_DATA_IMM.
683+ *
684+ * The following dwords have a reserved meaning:
685+ * 0: ISR copy, updated when an ISR bit not set in the HWSTAM changes.
686+ * 4: ring 0 head pointer
687+ * 5: ring 1 head pointer (915-class)
688+ * 6: ring 2 head pointer (915-class)
689 *
690- * The actual value is this field multiplied by two.
691+ * The area from dword 0x10 to 0x3ff is available for driver usage.
692 */
693-#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
694-#define BLM_LEGACY_MODE (1 << 16)
695-/**
696- * This is the number of cycles out of the backlight modulation cycle for which
697- * the backlight is on.
698- *
699- * This field must be no greater than the number of cycles in the complete
700- * backlight modulation cycle.
701- */
702-#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
703-#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
704-
705-#define I915_GCFGC 0xf0
706-#define I915_LOW_FREQUENCY_ENABLE (1 << 7)
707-#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
708-#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4)
709-#define I915_DISPLAY_CLOCK_MASK (7 << 4)
710-
711-#define I855_HPLLCC 0xc0
712-#define I855_CLOCK_CONTROL_MASK (3 << 0)
713-#define I855_CLOCK_133_200 (0 << 0)
714-#define I855_CLOCK_100_200 (1 << 0)
715-#define I855_CLOCK_100_133 (2 << 0)
716-#define I855_CLOCK_166_250 (3 << 0)
717-
718-/* p317, 319
719- */
720-#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */
721-#define VCLK2_VCO_N 0x600a
722-#define VCLK2_VCO_DIV_SEL 0x6012
723-
724-#define VCLK_DIVISOR_VGA0 0x6000
725-#define VCLK_DIVISOR_VGA1 0x6004
726-#define VCLK_POST_DIV 0x6010
727-/** Selects a post divisor of 4 instead of 2. */
728-# define VGA1_PD_P2_DIV_4 (1 << 15)
729-/** Overrides the p2 post divisor field */
730-# define VGA1_PD_P1_DIV_2 (1 << 13)
731-# define VGA1_PD_P1_SHIFT 8
732-/** P1 value is 2 greater than this field */
733-# define VGA1_PD_P1_MASK (0x1f << 8)
734-/** Selects a post divisor of 4 instead of 2. */
735-# define VGA0_PD_P2_DIV_4 (1 << 7)
736-/** Overrides the p2 post divisor field */
737-# define VGA0_PD_P1_DIV_2 (1 << 5)
738-# define VGA0_PD_P1_SHIFT 0
739-/** P1 value is 2 greater than this field */
740-# define VGA0_PD_P1_MASK (0x1f << 0)
741-
742-/* PCI D state control register */
743-#define D_STATE 0x6104
744-#define DSPCLK_GATE_D 0x6200
745-
746-/* I830 CRTC registers */
747-#define HTOTAL_A 0x60000
748-#define HBLANK_A 0x60004
749-#define HSYNC_A 0x60008
750-#define VTOTAL_A 0x6000c
751-#define VBLANK_A 0x60010
752-#define VSYNC_A 0x60014
753-#define PIPEASRC 0x6001c
754-#define BCLRPAT_A 0x60020
755-#define VSYNCSHIFT_A 0x60028
756-
757-#define HTOTAL_B 0x61000
758-#define HBLANK_B 0x61004
759-#define HSYNC_B 0x61008
760-#define VTOTAL_B 0x6100c
761-#define VBLANK_B 0x61010
762-#define VSYNC_B 0x61014
763-#define PIPEBSRC 0x6101c
764-#define BCLRPAT_B 0x61020
765-#define VSYNCSHIFT_B 0x61028
766-
767-#define PP_STATUS 0x61200
768-# define PP_ON (1 << 31)
769-/**
770- * Indicates that all dependencies of the panel are on:
771- *
772- * - PLL enabled
773- * - pipe enabled
774- * - LVDS/DVOB/DVOC on
775- */
776-# define PP_READY (1 << 30)
777-# define PP_SEQUENCE_NONE (0 << 28)
778-# define PP_SEQUENCE_ON (1 << 28)
779-# define PP_SEQUENCE_OFF (2 << 28)
780-# define PP_SEQUENCE_MASK 0x30000000
781-#define PP_CONTROL 0x61204
782-# define POWER_TARGET_ON (1 << 0)
783-
784-#define LVDSPP_ON 0x61208
785-#define LVDSPP_OFF 0x6120c
786-#define PP_CYCLE 0x61210
787-
788-#define PFIT_CONTROL 0x61230
789-# define PFIT_ENABLE (1 << 31)
790-# define PFIT_PIPE_MASK (3 << 29)
791-# define PFIT_PIPE_SHIFT 29
792-# define VERT_INTERP_DISABLE (0 << 10)
793-# define VERT_INTERP_BILINEAR (1 << 10)
794-# define VERT_INTERP_MASK (3 << 10)
795-# define VERT_AUTO_SCALE (1 << 9)
796-# define HORIZ_INTERP_DISABLE (0 << 6)
797-# define HORIZ_INTERP_BILINEAR (1 << 6)
798-# define HORIZ_INTERP_MASK (3 << 6)
799-# define HORIZ_AUTO_SCALE (1 << 5)
800-# define PANEL_8TO6_DITHER_ENABLE (1 << 3)
801-
802-#define PFIT_PGM_RATIOS 0x61234
803-# define PFIT_VERT_SCALE_MASK 0xfff00000
804-# define PFIT_HORIZ_SCALE_MASK 0x0000fff0
805-
806-#define PFIT_AUTO_RATIOS 0x61238
807-
808-
809-#define DPLL_A 0x06014
810-#define DPLL_B 0x06018
811-# define DPLL_VCO_ENABLE (1 << 31)
812-# define DPLL_DVO_HIGH_SPEED (1 << 30)
813-# define DPLL_SYNCLOCK_ENABLE (1 << 29)
814-# define DPLL_VGA_MODE_DIS (1 << 28)
815-# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
816-# define DPLLB_MODE_LVDS (2 << 26) /* i915 */
817-# define DPLL_MODE_MASK (3 << 26)
818-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
819-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
820-# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
821-# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
822-# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
823-# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
824-/**
825- * The i830 generation, in DAC/serial mode, defines p1 as two plus this
826- * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
827- */
828-# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
829-/**
830- * The i830 generation, in LVDS mode, defines P1 as the bit number set within
831- * this field (only one bit may be set).
832- */
833-# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
834-# define DPLL_FPA01_P1_POST_DIV_SHIFT 16
835-# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */
836-# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
837-# define PLL_REF_INPUT_DREFCLK (0 << 13)
838-# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
839-# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
840-# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
841-# define PLL_REF_INPUT_MASK (3 << 13)
842-# define PLL_LOAD_PULSE_PHASE_SHIFT 9
843-/*
844- * Parallel to Serial Load Pulse phase selection.
845- * Selects the phase for the 10X DPLL clock for the PCIe
846- * digital display port. The range is 4 to 13; 10 or more
847- * is just a flip delay. The default is 6
848- */
849-# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
850-# define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
851-
852-/**
853- * SDVO multiplier for 945G/GM. Not used on 965.
854- *
855- * \sa DPLL_MD_UDI_MULTIPLIER_MASK
856- */
857-# define SDVO_MULTIPLIER_MASK 0x000000ff
858-# define SDVO_MULTIPLIER_SHIFT_HIRES 4
859-# define SDVO_MULTIPLIER_SHIFT_VGA 0
860-
861-/** @defgroup DPLL_MD
862- * @{
863- */
864-/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */
865-#define DPLL_A_MD 0x0601c
866-/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */
867-#define DPLL_B_MD 0x06020
868-/**
869- * UDI pixel divider, controlling how many pixels are stuffed into a packet.
870- *
871- * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
872- */
873-# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
874-# define DPLL_MD_UDI_DIVIDER_SHIFT 24
875-/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
876-# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
877-# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
878-/**
879- * SDVO/UDI pixel multiplier.
880- *
881- * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
882- * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
883- * modes, the bus rate would be below the limits, so SDVO allows for stuffing
884- * dummy bytes in the datastream at an increased clock rate, with both sides of
885- * the link knowing how many bytes are fill.
886- *
887- * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
888- * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
889- * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
890- * through an SDVO command.
891- *
892- * This register field has values of multiplication factor minus 1, with
893- * a maximum multiplier of 5 for SDVO.
894- */
895-# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
896-# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
897-/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
898- * This best be set to the default value (3) or the CRT won't work. No,
899- * I don't entirely understand what this does...
900- */
901-# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
902-# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
903-/** @} */
904-
905-#define DPLL_TEST 0x606c
906-# define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
907-# define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
908-# define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
909-# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
910-# define DPLLB_TEST_N_BYPASS (1 << 19)
911-# define DPLLB_TEST_M_BYPASS (1 << 18)
912-# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
913-# define DPLLA_TEST_N_BYPASS (1 << 3)
914-# define DPLLA_TEST_M_BYPASS (1 << 2)
915-# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
916-
917-#define ADPA 0x61100
918-#define ADPA_DAC_ENABLE (1<<31)
919-#define ADPA_DAC_DISABLE 0
920-#define ADPA_PIPE_SELECT_MASK (1<<30)
921-#define ADPA_PIPE_A_SELECT 0
922-#define ADPA_PIPE_B_SELECT (1<<30)
923-#define ADPA_USE_VGA_HVPOLARITY (1<<15)
924-#define ADPA_SETS_HVPOLARITY 0
925-#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
926-#define ADPA_VSYNC_CNTL_ENABLE 0
927-#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
928-#define ADPA_HSYNC_CNTL_ENABLE 0
929-#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
930-#define ADPA_VSYNC_ACTIVE_LOW 0
931-#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
932-#define ADPA_HSYNC_ACTIVE_LOW 0
933-
934-#define FPA0 0x06040
935-#define FPA1 0x06044
936-#define FPB0 0x06048
937-#define FPB1 0x0604c
938-# define FP_N_DIV_MASK 0x003f0000
939-# define FP_N_DIV_SHIFT 16
940-# define FP_M1_DIV_MASK 0x00003f00
941-# define FP_M1_DIV_SHIFT 8
942-# define FP_M2_DIV_MASK 0x0000003f
943-# define FP_M2_DIV_SHIFT 0
944-
945-
946-#define PORT_HOTPLUG_EN 0x61110
947-# define SDVOB_HOTPLUG_INT_EN (1 << 26)
948-# define SDVOC_HOTPLUG_INT_EN (1 << 25)
949-# define TV_HOTPLUG_INT_EN (1 << 18)
950-# define CRT_HOTPLUG_INT_EN (1 << 9)
951-# define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
952-
953-#define PORT_HOTPLUG_STAT 0x61114
954-# define CRT_HOTPLUG_INT_STATUS (1 << 11)
955-# define TV_HOTPLUG_INT_STATUS (1 << 10)
956-# define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
957-# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
958-# define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
959-# define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
960-# define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
961-# define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
962-
963-#define SDVOB 0x61140
964-#define SDVOC 0x61160
965-#define SDVO_ENABLE (1 << 31)
966-#define SDVO_PIPE_B_SELECT (1 << 30)
967-#define SDVO_STALL_SELECT (1 << 29)
968-#define SDVO_INTERRUPT_ENABLE (1 << 26)
969-/**
970- * 915G/GM SDVO pixel multiplier.
971- *
972- * Programmed value is multiplier - 1, up to 5x.
973- *
974- * \sa DPLL_MD_UDI_MULTIPLIER_MASK
975- */
976-#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
977-#define SDVO_PORT_MULTIPLY_SHIFT 23
978-#define SDVO_PHASE_SELECT_MASK (15 << 19)
979-#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
980-#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
981-#define SDVOC_GANG_MODE (1 << 16)
982-#define SDVO_BORDER_ENABLE (1 << 7)
983-#define SDVOB_PCIE_CONCURRENCY (1 << 3)
984-#define SDVO_DETECTED (1 << 2)
985-/* Bits to be preserved when writing */
986-#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14))
987-#define SDVOC_PRESERVE_MASK (1 << 17)
988-
989-/** @defgroup LVDS
990- * @{
991- */
992-/**
993- * This register controls the LVDS output enable, pipe selection, and data
994- * format selection.
995- *
996- * All of the clock/data pairs are force powered down by power sequencing.
997- */
998-#define LVDS 0x61180
999-/**
1000- * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
1001- * the DPLL semantics change when the LVDS is assigned to that pipe.
1002- */
1003-# define LVDS_PORT_EN (1 << 31)
1004-/** Selects pipe B for LVDS data. Must be set on pre-965. */
1005-# define LVDS_PIPEB_SELECT (1 << 30)
1006-
1007-/**
1008- * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
1009- * pixel.
1010- */
1011-# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
1012-# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
1013-# define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
1014-/**
1015- * Controls the A3 data pair, which contains the additional LSBs for 24 bit
1016- * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
1017- * on.
1018- */
1019-# define LVDS_A3_POWER_MASK (3 << 6)
1020-# define LVDS_A3_POWER_DOWN (0 << 6)
1021-# define LVDS_A3_POWER_UP (3 << 6)
1022-/**
1023- * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
1024- * is set.
1025- */
1026-# define LVDS_CLKB_POWER_MASK (3 << 4)
1027-# define LVDS_CLKB_POWER_DOWN (0 << 4)
1028-# define LVDS_CLKB_POWER_UP (3 << 4)
1029-
1030-/**
1031- * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
1032- * setting for whether we are in dual-channel mode. The B3 pair will
1033- * additionally only be powered up when LVDS_A3_POWER_UP is set.
1034- */
1035-# define LVDS_B0B3_POWER_MASK (3 << 2)
1036-# define LVDS_B0B3_POWER_DOWN (0 << 2)
1037-# define LVDS_B0B3_POWER_UP (3 << 2)
1038-
1039-#define PIPEACONF 0x70008
1040-#define PIPEACONF_ENABLE (1<<31)
1041-#define PIPEACONF_DISABLE 0
1042-#define PIPEACONF_DOUBLE_WIDE (1<<30)
1043-#define I965_PIPECONF_ACTIVE (1<<30)
1044-#define PIPEACONF_SINGLE_WIDE 0
1045-#define PIPEACONF_PIPE_UNLOCKED 0
1046-#define PIPEACONF_PIPE_LOCKED (1<<25)
1047-#define PIPEACONF_PALETTE 0
1048-#define PIPEACONF_GAMMA (1<<24)
1049-#define PIPECONF_FORCE_BORDER (1<<25)
1050-#define PIPECONF_PROGRESSIVE (0 << 21)
1051-#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
1052-#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
1053-
1054-#define DSPARB 0x70030
1055-#define DSPARB_CSTART_MASK (0x7f << 7)
1056-#define DSPARB_CSTART_SHIFT 7
1057-#define DSPARB_BSTART_MASK (0x7f)
1058-#define DSPARB_BSTART_SHIFT 0
1059-
1060-#define PIPEBCONF 0x71008
1061-#define PIPEBCONF_ENABLE (1<<31)
1062-#define PIPEBCONF_DISABLE 0
1063-#define PIPEBCONF_DOUBLE_WIDE (1<<30)
1064-#define PIPEBCONF_DISABLE 0
1065-#define PIPEBCONF_GAMMA (1<<24)
1066-#define PIPEBCONF_PALETTE 0
1067-
1068-#define PIPEBGCMAXRED 0x71010
1069-#define PIPEBGCMAXGREEN 0x71014
1070-#define PIPEBGCMAXBLUE 0x71018
1071-#define PIPEBSTAT 0x71024
1072-#define PIPEBFRAMEHIGH 0x71040
1073-#define PIPEBFRAMEPIXEL 0x71044
1074-
1075-#define DSPACNTR 0x70180
1076-#define DSPBCNTR 0x71180
1077-#define DISPLAY_PLANE_ENABLE (1<<31)
1078-#define DISPLAY_PLANE_DISABLE 0
1079-#define DISPPLANE_GAMMA_ENABLE (1<<30)
1080-#define DISPPLANE_GAMMA_DISABLE 0
1081-#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
1082-#define DISPPLANE_8BPP (0x2<<26)
1083-#define DISPPLANE_15_16BPP (0x4<<26)
1084-#define DISPPLANE_16BPP (0x5<<26)
1085-#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
1086-#define DISPPLANE_32BPP (0x7<<26)
1087-#define DISPPLANE_STEREO_ENABLE (1<<25)
1088-#define DISPPLANE_STEREO_DISABLE 0
1089-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
1090-#define DISPPLANE_SEL_PIPE_A 0
1091-#define DISPPLANE_SEL_PIPE_B (1<<24)
1092-#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
1093-#define DISPPLANE_SRC_KEY_DISABLE 0
1094-#define DISPPLANE_LINE_DOUBLE (1<<20)
1095-#define DISPPLANE_NO_LINE_DOUBLE 0
1096-#define DISPPLANE_STEREO_POLARITY_FIRST 0
1097-#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
1098-/* plane B only */
1099-#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
1100-#define DISPPLANE_ALPHA_TRANS_DISABLE 0
1101-#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0
1102-#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
1103-
1104-#define DSPABASE 0x70184
1105-#define DSPASTRIDE 0x70188
1106-
1107-#define DSPBBASE 0x71184
1108-#define DSPBADDR DSPBBASE
1109-#define DSPBSTRIDE 0x71188
1110-
1111-#define DSPAKEYVAL 0x70194
1112-#define DSPAKEYMASK 0x70198
1113-
1114-#define DSPAPOS 0x7018C /* reserved */
1115-#define DSPASIZE 0x70190
1116-#define DSPBPOS 0x7118C
1117-#define DSPBSIZE 0x71190
1118-
1119-#define DSPASURF 0x7019C
1120-#define DSPATILEOFF 0x701A4
1121-
1122-#define DSPBSURF 0x7119C
1123-#define DSPBTILEOFF 0x711A4
1124-
1125-#define VGACNTRL 0x71400
1126-# define VGA_DISP_DISABLE (1 << 31)
1127-# define VGA_2X_MODE (1 << 30)
1128-# define VGA_PIPE_B_SELECT (1 << 29)
1129-
1130-/*
1131- * Some BIOS scratch area registers. The 845 (and 830?) store the amount
1132- * of video memory available to the BIOS in SWF1.
1133- */
1134-
1135-#define SWF0 0x71410
1136-
1137-/*
1138- * 855 scratch registers.
1139- */
1140-#define SWF10 0x70410
1141-
1142-#define SWF30 0x72414
1143-
1144-/*
1145- * Overlay registers. These are overlay registers accessed via MMIO.
1146- * Those loaded via the overlay register page are defined in i830_video.c.
1147- */
1148-#define OVADD 0x30000
1149-
1150-#define DOVSTA 0x30008
1151-#define OC_BUF (0x3<<20)
1152+#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
1153+#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5)
1154
1155-#define OGAMC5 0x30010
1156-#define OGAMC4 0x30014
1157-#define OGAMC3 0x30018
1158-#define OGAMC2 0x3001c
1159-#define OGAMC1 0x30020
1160-#define OGAMC0 0x30024
1161-/*
1162- * Palette registers
1163- */
1164-#define PALETTE_A 0x0a000
1165-#define PALETTE_B 0x0a800
1166+extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1167
1168 #define IS_I830(dev) ((dev)->pci_device == 0x3577)
1169 #define IS_845G(dev) ((dev)->pci_device == 0x2562)
1170--- a/drivers/gpu/drm/i915/i915_irq.c
1171+++ b/drivers/gpu/drm/i915/i915_irq.c
1172@@ -31,10 +31,6 @@
1173 #include "i915_drm.h"
1174 #include "i915_drv.h"
1175
1176-#define USER_INT_FLAG (1<<1)
1177-#define VSYNC_PIPEB_FLAG (1<<5)
1178-#define VSYNC_PIPEA_FLAG (1<<7)
1179-
1180 #define MAX_NOPID ((u32)~0)
1181
1182 /**
1183@@ -236,40 +232,43 @@ irqreturn_t i915_driver_irq_handler(DRM_
1184 u16 temp;
1185 u32 pipea_stats, pipeb_stats;
1186
1187- pipea_stats = I915_READ(I915REG_PIPEASTAT);
1188- pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
1189+ pipea_stats = I915_READ(PIPEASTAT);
1190+ pipeb_stats = I915_READ(PIPEBSTAT);
1191
1192- temp = I915_READ16(I915REG_INT_IDENTITY_R);
1193+ temp = I915_READ16(IIR);
1194
1195- temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG);
1196+ temp &= (I915_USER_INTERRUPT |
1197+ I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
1198+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT);
1199
1200 DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
1201
1202 if (temp == 0)
1203 return IRQ_NONE;
1204
1205- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
1206- (void) I915_READ16(I915REG_INT_IDENTITY_R);
1207+ I915_WRITE16(IIR, temp);
1208+ (void) I915_READ16(IIR);
1209 DRM_READMEMORYBARRIER();
1210
1211 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
1212
1213- if (temp & USER_INT_FLAG)
1214+ if (temp & I915_USER_INTERRUPT)
1215 DRM_WAKEUP(&dev_priv->irq_queue);
1216
1217- if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
1218+ if (temp & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
1219+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
1220 int vblank_pipe = dev_priv->vblank_pipe;
1221
1222 if ((vblank_pipe &
1223 (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
1224 == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
1225- if (temp & VSYNC_PIPEA_FLAG)
1226+ if (temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
1227 atomic_inc(&dev->vbl_received);
1228- if (temp & VSYNC_PIPEB_FLAG)
1229+ if (temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
1230 atomic_inc(&dev->vbl_received2);
1231- } else if (((temp & VSYNC_PIPEA_FLAG) &&
1232+ } else if (((temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
1233 (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
1234- ((temp & VSYNC_PIPEB_FLAG) &&
1235+ ((temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
1236 (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
1237 atomic_inc(&dev->vbl_received);
1238
1239@@ -278,12 +277,12 @@ irqreturn_t i915_driver_irq_handler(DRM_
1240
1241 if (dev_priv->swaps_pending > 0)
1242 drm_locked_tasklet(dev, i915_vblank_tasklet);
1243- I915_WRITE(I915REG_PIPEASTAT,
1244+ I915_WRITE(PIPEASTAT,
1245 pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
1246- I915_VBLANK_CLEAR);
1247- I915_WRITE(I915REG_PIPEBSTAT,
1248+ PIPE_VBLANK_INTERRUPT_STATUS);
1249+ I915_WRITE(PIPEBSTAT,
1250 pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
1251- I915_VBLANK_CLEAR);
1252+ PIPE_VBLANK_INTERRUPT_STATUS);
1253 }
1254
1255 return IRQ_HANDLED;
1256@@ -304,12 +303,12 @@ static int i915_emit_irq(struct drm_devi
1257 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
1258
1259 BEGIN_LP_RING(6);
1260- OUT_RING(CMD_STORE_DWORD_IDX);
1261- OUT_RING(20);
1262+ OUT_RING(MI_STORE_DWORD_INDEX);
1263+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
1264 OUT_RING(dev_priv->counter);
1265 OUT_RING(0);
1266 OUT_RING(0);
1267- OUT_RING(GFX_OP_USER_INTERRUPT);
1268+ OUT_RING(MI_USER_INTERRUPT);
1269 ADVANCE_LP_RING();
1270
1271 return dev_priv->counter;
1272@@ -421,11 +420,11 @@ static void i915_enable_interrupt (struc
1273
1274 flag = 0;
1275 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
1276- flag |= VSYNC_PIPEA_FLAG;
1277+ flag |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1278 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
1279- flag |= VSYNC_PIPEB_FLAG;
1280+ flag |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1281
1282- I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag);
1283+ I915_WRITE16(IER, I915_USER_INTERRUPT | flag);
1284 }
1285
1286 /* Set the vblank monitor pipe
1287@@ -465,11 +464,11 @@ int i915_vblank_pipe_get(struct drm_devi
1288 return -EINVAL;
1289 }
1290
1291- flag = I915_READ(I915REG_INT_ENABLE_R);
1292+ flag = I915_READ(IER);
1293 pipe->pipe = 0;
1294- if (flag & VSYNC_PIPEA_FLAG)
1295+ if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
1296 pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
1297- if (flag & VSYNC_PIPEB_FLAG)
1298+ if (flag & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
1299 pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
1300
1301 return 0;
1302@@ -587,9 +586,9 @@ void i915_driver_irq_preinstall(struct d
1303 {
1304 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1305
1306- I915_WRITE16(I915REG_HWSTAM, 0xfffe);
1307- I915_WRITE16(I915REG_INT_MASK_R, 0x0);
1308- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
1309+ I915_WRITE16(HWSTAM, 0xfffe);
1310+ I915_WRITE16(IMR, 0x0);
1311+ I915_WRITE16(IER, 0x0);
1312 }
1313
1314 void i915_driver_irq_postinstall(struct drm_device * dev)
1315@@ -614,10 +613,10 @@ void i915_driver_irq_uninstall(struct dr
1316 if (!dev_priv)
1317 return;
1318
1319- I915_WRITE16(I915REG_HWSTAM, 0xffff);
1320- I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
1321- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
1322+ I915_WRITE16(HWSTAM, 0xffff);
1323+ I915_WRITE16(IMR, 0xffff);
1324+ I915_WRITE16(IER, 0x0);
1325
1326- temp = I915_READ16(I915REG_INT_IDENTITY_R);
1327- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
1328+ temp = I915_READ16(IIR);
1329+ I915_WRITE16(IIR, temp);
1330 }
1331--- /dev/null
1332+++ b/drivers/gpu/drm/i915/i915_reg.h
1333@@ -0,0 +1,1405 @@
1334+/* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
1335+ * All Rights Reserved.
1336+ *
1337+ * Permission is hereby granted, free of charge, to any person obtaining a
1338+ * copy of this software and associated documentation files (the
1339+ * "Software"), to deal in the Software without restriction, including
1340+ * without limitation the rights to use, copy, modify, merge, publish,
1341+ * distribute, sub license, and/or sell copies of the Software, and to
1342+ * permit persons to whom the Software is furnished to do so, subject to
1343+ * the following conditions:
1344+ *
1345+ * The above copyright notice and this permission notice (including the
1346+ * next paragraph) shall be included in all copies or substantial portions
1347+ * of the Software.
1348+ *
1349+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1350+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1351+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
1352+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
1353+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1354+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1355+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1356+ */
1357+
1358+#ifndef _I915_REG_H_
1359+#define _I915_REG_H_
1360+
1361+/* MCH MMIO space */
1362+/** 915-945 and GM965 MCH register controlling DRAM channel access */
1363+#define DCC 0x200
1364+#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
1365+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
1366+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
1367+#define DCC_ADDRESSING_MODE_MASK (3 << 0)
1368+#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
1369+
1370+/** 965 MCH register controlling DRAM channel configuration */
1371+#define CHDECMISC 0x111
1372+#define CHDECMISC_FLEXMEMORY (1 << 1)
1373+
1374+/*
1375+ * The Bridge device's PCI config space has information about the
1376+ * fb aperture size and the amount of pre-reserved memory.
1377+ */
1378+#define INTEL_GMCH_CTRL 0x52
1379+#define INTEL_GMCH_ENABLED 0x4
1380+#define INTEL_GMCH_MEM_MASK 0x1
1381+#define INTEL_GMCH_MEM_64M 0x1
1382+#define INTEL_GMCH_MEM_128M 0
1383+
1384+#define INTEL_855_GMCH_GMS_MASK (0x7 << 4)
1385+#define INTEL_855_GMCH_GMS_DISABLED (0x0 << 4)
1386+#define INTEL_855_GMCH_GMS_STOLEN_1M (0x1 << 4)
1387+#define INTEL_855_GMCH_GMS_STOLEN_4M (0x2 << 4)
1388+#define INTEL_855_GMCH_GMS_STOLEN_8M (0x3 << 4)
1389+#define INTEL_855_GMCH_GMS_STOLEN_16M (0x4 << 4)
1390+#define INTEL_855_GMCH_GMS_STOLEN_32M (0x5 << 4)
1391+
1392+#define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4)
1393+#define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
1394+
1395+/* PCI config space */
1396+
1397+#define HPLLCC 0xc0 /* 855 only */
1398+#define GC_CLOCK_CONTROL_MASK (3 << 0)
1399+#define GC_CLOCK_133_200 (0 << 0)
1400+#define GC_CLOCK_100_200 (1 << 0)
1401+#define GC_CLOCK_100_133 (2 << 0)
1402+#define GC_CLOCK_166_250 (3 << 0)
1403+#define GCFGC 0xf0 /* 915+ only */
1404+#define GC_LOW_FREQUENCY_ENABLE (1 << 7)
1405+#define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
1406+#define GC_DISPLAY_CLOCK_333_MHZ (4 << 4)
1407+#define GC_DISPLAY_CLOCK_MASK (7 << 4)
1408+#define LBB 0xf4
1409+
1410+/* VGA stuff */
1411+
1412+#define VGA_ST01_MDA 0x3ba
1413+#define VGA_ST01_CGA 0x3da
1414+
1415+#define VGA_MSR_WRITE 0x3c2
1416+#define VGA_MSR_READ 0x3cc
1417+#define VGA_MSR_MEM_EN (1<<1)
1418+#define VGA_MSR_CGA_MODE (1<<0)
1419+
1420+#define VGA_SR_INDEX 0x3c4
1421+#define VGA_SR_DATA 0x3c5
1422+
1423+#define VGA_AR_INDEX 0x3c0
1424+#define VGA_AR_VID_EN (1<<5)
1425+#define VGA_AR_DATA_WRITE 0x3c0
1426+#define VGA_AR_DATA_READ 0x3c1
1427+
1428+#define VGA_GR_INDEX 0x3ce
1429+#define VGA_GR_DATA 0x3cf
1430+/* GR05 */
1431+#define VGA_GR_MEM_READ_MODE_SHIFT 3
1432+#define VGA_GR_MEM_READ_MODE_PLANE 1
1433+/* GR06 */
1434+#define VGA_GR_MEM_MODE_MASK 0xc
1435+#define VGA_GR_MEM_MODE_SHIFT 2
1436+#define VGA_GR_MEM_A0000_AFFFF 0
1437+#define VGA_GR_MEM_A0000_BFFFF 1
1438+#define VGA_GR_MEM_B0000_B7FFF 2
1439+#define VGA_GR_MEM_B0000_BFFFF 3
1440+
1441+#define VGA_DACMASK 0x3c6
1442+#define VGA_DACRX 0x3c7
1443+#define VGA_DACWX 0x3c8
1444+#define VGA_DACDATA 0x3c9
1445+
1446+#define VGA_CR_INDEX_MDA 0x3b4
1447+#define VGA_CR_DATA_MDA 0x3b5
1448+#define VGA_CR_INDEX_CGA 0x3d4
1449+#define VGA_CR_DATA_CGA 0x3d5
1450+
1451+/*
1452+ * Memory interface instructions used by the kernel
1453+ */
1454+#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
1455+
1456+#define MI_NOOP MI_INSTR(0, 0)
1457+#define MI_USER_INTERRUPT MI_INSTR(0x02, 0)
1458+#define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0)
1459+#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
1460+#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
1461+#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
1462+#define MI_FLUSH MI_INSTR(0x04, 0)
1463+#define MI_READ_FLUSH (1 << 0)
1464+#define MI_EXE_FLUSH (1 << 1)
1465+#define MI_NO_WRITE_FLUSH (1 << 2)
1466+#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
1467+#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
1468+#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0)
1469+#define MI_REPORT_HEAD MI_INSTR(0x07, 0)
1470+#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
1471+#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
1472+#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
1473+#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
1474+#define MI_STORE_DWORD_INDEX_SHIFT 2
1475+#define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1)
1476+#define MI_BATCH_BUFFER MI_INSTR(0x30, 1)
1477+#define MI_BATCH_NON_SECURE (1)
1478+#define MI_BATCH_NON_SECURE_I965 (1<<8)
1479+#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0)
1480+
1481+/*
1482+ * 3D instructions used by the kernel
1483+ */
1484+#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags))
1485+
1486+#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
1487+#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
1488+#define SC_UPDATE_SCISSOR (0x1<<1)
1489+#define SC_ENABLE_MASK (0x1<<0)
1490+#define SC_ENABLE (0x1<<0)
1491+#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
1492+#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
1493+#define SCI_YMIN_MASK (0xffff<<16)
1494+#define SCI_XMIN_MASK (0xffff<<0)
1495+#define SCI_YMAX_MASK (0xffff<<16)
1496+#define SCI_XMAX_MASK (0xffff<<0)
1497+#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
1498+#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
1499+#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
1500+#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
1501+#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
1502+#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
1503+#define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
1504+#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
1505+#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
1506+#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
1507+#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
1508+#define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5)
1509+#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
1510+#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
1511+#define BLT_DEPTH_8 (0<<24)
1512+#define BLT_DEPTH_16_565 (1<<24)
1513+#define BLT_DEPTH_16_1555 (2<<24)
1514+#define BLT_DEPTH_32 (3<<24)
1515+#define BLT_ROP_GXCOPY (0xcc<<16)
1516+#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */
1517+#define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */
1518+#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
1519+#define ASYNC_FLIP (1<<22)
1520+#define DISPLAY_PLANE_A (0<<20)
1521+#define DISPLAY_PLANE_B (1<<20)
1522+
1523+/*
1524+ * Instruction and interrupt control regs
1525+ */
1526+
1527+#define PRB0_TAIL 0x02030
1528+#define PRB0_HEAD 0x02034
1529+#define PRB0_START 0x02038
1530+#define PRB0_CTL 0x0203c
1531+#define TAIL_ADDR 0x001FFFF8
1532+#define HEAD_WRAP_COUNT 0xFFE00000
1533+#define HEAD_WRAP_ONE 0x00200000
1534+#define HEAD_ADDR 0x001FFFFC
1535+#define RING_NR_PAGES 0x001FF000
1536+#define RING_REPORT_MASK 0x00000006
1537+#define RING_REPORT_64K 0x00000002
1538+#define RING_REPORT_128K 0x00000004
1539+#define RING_NO_REPORT 0x00000000
1540+#define RING_VALID_MASK 0x00000001
1541+#define RING_VALID 0x00000001
1542+#define RING_INVALID 0x00000000
1543+#define PRB1_TAIL 0x02040 /* 915+ only */
1544+#define PRB1_HEAD 0x02044 /* 915+ only */
1545+#define PRB1_START 0x02048 /* 915+ only */
1546+#define PRB1_CTL 0x0204c /* 915+ only */
1547+#define ACTHD_I965 0x02074
1548+#define HWS_PGA 0x02080
1549+#define HWS_ADDRESS_MASK 0xfffff000
1550+#define HWS_START_ADDRESS_SHIFT 4
1551+#define IPEIR 0x02088
1552+#define NOPID 0x02094
1553+#define HWSTAM 0x02098
1554+#define SCPD0 0x0209c /* 915+ only */
1555+#define IER 0x020a0
1556+#define IIR 0x020a4
1557+#define IMR 0x020a8
1558+#define ISR 0x020ac
1559+#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18)
1560+#define I915_DISPLAY_PORT_INTERRUPT (1<<17)
1561+#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15)
1562+#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14)
1563+#define I915_HWB_OOM_INTERRUPT (1<<13)
1564+#define I915_SYNC_STATUS_INTERRUPT (1<<12)
1565+#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11)
1566+#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10)
1567+#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9)
1568+#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8)
1569+#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7)
1570+#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6)
1571+#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5)
1572+#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4)
1573+#define I915_DEBUG_INTERRUPT (1<<2)
1574+#define I915_USER_INTERRUPT (1<<1)
1575+#define I915_ASLE_INTERRUPT (1<<0)
1576+#define EIR 0x020b0
1577+#define EMR 0x020b4
1578+#define ESR 0x020b8
1579+#define INSTPM 0x020c0
1580+#define ACTHD 0x020c8
1581+#define FW_BLC 0x020d8
1582+#define FW_BLC_SELF 0x020e0 /* 915+ only */
1583+#define MI_ARB_STATE 0x020e4 /* 915+ only */
1584+#define CACHE_MODE_0 0x02120 /* 915+ only */
1585+#define CM0_MASK_SHIFT 16
1586+#define CM0_IZ_OPT_DISABLE (1<<6)
1587+#define CM0_ZR_OPT_DISABLE (1<<5)
1588+#define CM0_DEPTH_EVICT_DISABLE (1<<4)
1589+#define CM0_COLOR_EVICT_DISABLE (1<<3)
1590+#define CM0_DEPTH_WRITE_DISABLE (1<<1)
1591+#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
1592+#define GFX_FLSH_CNTL 0x02170 /* 915+ only */
1593+
1594+/*
1595+ * Framebuffer compression (915+ only)
1596+ */
1597+
1598+#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
1599+#define FBC_LL_BASE 0x03204 /* 4k page aligned */
1600+#define FBC_CONTROL 0x03208
1601+#define FBC_CTL_EN (1<<31)
1602+#define FBC_CTL_PERIODIC (1<<30)
1603+#define FBC_CTL_INTERVAL_SHIFT (16)
1604+#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
1605+#define FBC_CTL_STRIDE_SHIFT (5)
1606+#define FBC_CTL_FENCENO (1<<0)
1607+#define FBC_COMMAND 0x0320c
1608+#define FBC_CMD_COMPRESS (1<<0)
1609+#define FBC_STATUS 0x03210
1610+#define FBC_STAT_COMPRESSING (1<<31)
1611+#define FBC_STAT_COMPRESSED (1<<30)
1612+#define FBC_STAT_MODIFIED (1<<29)
1613+#define FBC_STAT_CURRENT_LINE (1<<0)
1614+#define FBC_CONTROL2 0x03214
1615+#define FBC_CTL_FENCE_DBL (0<<4)
1616+#define FBC_CTL_IDLE_IMM (0<<2)
1617+#define FBC_CTL_IDLE_FULL (1<<2)
1618+#define FBC_CTL_IDLE_LINE (2<<2)
1619+#define FBC_CTL_IDLE_DEBUG (3<<2)
1620+#define FBC_CTL_CPU_FENCE (1<<1)
1621+#define FBC_CTL_PLANEA (0<<0)
1622+#define FBC_CTL_PLANEB (1<<0)
1623+#define FBC_FENCE_OFF 0x0321b
1624+
1625+#define FBC_LL_SIZE (1536)
1626+
1627+/*
1628+ * GPIO regs
1629+ */
1630+#define GPIOA 0x5010
1631+#define GPIOB 0x5014
1632+#define GPIOC 0x5018
1633+#define GPIOD 0x501c
1634+#define GPIOE 0x5020
1635+#define GPIOF 0x5024
1636+#define GPIOG 0x5028
1637+#define GPIOH 0x502c
1638+# define GPIO_CLOCK_DIR_MASK (1 << 0)
1639+# define GPIO_CLOCK_DIR_IN (0 << 1)
1640+# define GPIO_CLOCK_DIR_OUT (1 << 1)
1641+# define GPIO_CLOCK_VAL_MASK (1 << 2)
1642+# define GPIO_CLOCK_VAL_OUT (1 << 3)
1643+# define GPIO_CLOCK_VAL_IN (1 << 4)
1644+# define GPIO_CLOCK_PULLUP_DISABLE (1 << 5)
1645+# define GPIO_DATA_DIR_MASK (1 << 8)
1646+# define GPIO_DATA_DIR_IN (0 << 9)
1647+# define GPIO_DATA_DIR_OUT (1 << 9)
1648+# define GPIO_DATA_VAL_MASK (1 << 10)
1649+# define GPIO_DATA_VAL_OUT (1 << 11)
1650+# define GPIO_DATA_VAL_IN (1 << 12)
1651+# define GPIO_DATA_PULLUP_DISABLE (1 << 13)
1652+
1653+/*
1654+ * Clock control & power management
1655+ */
1656+
1657+#define VGA0 0x6000
1658+#define VGA1 0x6004
1659+#define VGA_PD 0x6010
1660+#define VGA0_PD_P2_DIV_4 (1 << 7)
1661+#define VGA0_PD_P1_DIV_2 (1 << 5)
1662+#define VGA0_PD_P1_SHIFT 0
1663+#define VGA0_PD_P1_MASK (0x1f << 0)
1664+#define VGA1_PD_P2_DIV_4 (1 << 15)
1665+#define VGA1_PD_P1_DIV_2 (1 << 13)
1666+#define VGA1_PD_P1_SHIFT 8
1667+#define VGA1_PD_P1_MASK (0x1f << 8)
1668+#define DPLL_A 0x06014
1669+#define DPLL_B 0x06018
1670+#define DPLL_VCO_ENABLE (1 << 31)
1671+#define DPLL_DVO_HIGH_SPEED (1 << 30)
1672+#define DPLL_SYNCLOCK_ENABLE (1 << 29)
1673+#define DPLL_VGA_MODE_DIS (1 << 28)
1674+#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
1675+#define DPLLB_MODE_LVDS (2 << 26) /* i915 */
1676+#define DPLL_MODE_MASK (3 << 26)
1677+#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
1678+#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
1679+#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
1680+#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
1681+#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
1682+#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
1683+
1684+#define I915_FIFO_UNDERRUN_STATUS (1UL<<31)
1685+#define I915_CRC_ERROR_ENABLE (1UL<<29)
1686+#define I915_CRC_DONE_ENABLE (1UL<<28)
1687+#define I915_GMBUS_EVENT_ENABLE (1UL<<27)
1688+#define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25)
1689+#define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
1690+#define I915_DPST_EVENT_ENABLE (1UL<<23)
1691+#define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
1692+#define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
1693+#define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
1694+#define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
1695+#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
1696+#define I915_OVERLAY_UPDATED_ENABLE (1UL<<16)
1697+#define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
1698+#define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
1699+#define I915_GMBUS_INTERRUPT_STATUS (1UL<<11)
1700+#define I915_VSYNC_INTERRUPT_STATUS (1UL<<9)
1701+#define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
1702+#define I915_DPST_EVENT_STATUS (1UL<<7)
1703+#define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6)
1704+#define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
1705+#define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
1706+#define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
1707+#define I915_VBLANK_INTERRUPT_STATUS (1UL<<1)
1708+#define I915_OVERLAY_UPDATED_STATUS (1UL<<0)
1709+
1710+#define SRX_INDEX 0x3c4
1711+#define SRX_DATA 0x3c5
1712+#define SR01 1
1713+#define SR01_SCREEN_OFF (1<<5)
1714+
1715+#define PPCR 0x61204
1716+#define PPCR_ON (1<<0)
1717+
1718+#define DVOB 0x61140
1719+#define DVOB_ON (1<<31)
1720+#define DVOC 0x61160
1721+#define DVOC_ON (1<<31)
1722+#define LVDS 0x61180
1723+#define LVDS_ON (1<<31)
1724+
1725+#define ADPA 0x61100
1726+#define ADPA_DPMS_MASK (~(3<<10))
1727+#define ADPA_DPMS_ON (0<<10)
1728+#define ADPA_DPMS_SUSPEND (1<<10)
1729+#define ADPA_DPMS_STANDBY (2<<10)
1730+#define ADPA_DPMS_OFF (3<<10)
1731+
1732+#define RING_TAIL 0x00
1733+#define TAIL_ADDR 0x001FFFF8
1734+#define RING_HEAD 0x04
1735+#define HEAD_WRAP_COUNT 0xFFE00000
1736+#define HEAD_WRAP_ONE 0x00200000
1737+#define HEAD_ADDR 0x001FFFFC
1738+#define RING_START 0x08
1739+#define START_ADDR 0xFFFFF000
1740+#define RING_LEN 0x0C
1741+#define RING_NR_PAGES 0x001FF000
1742+#define RING_REPORT_MASK 0x00000006
1743+#define RING_REPORT_64K 0x00000002
1744+#define RING_REPORT_128K 0x00000004
1745+#define RING_NO_REPORT 0x00000000
1746+#define RING_VALID_MASK 0x00000001
1747+#define RING_VALID 0x00000001
1748+#define RING_INVALID 0x00000000
1749+
1750+/* Scratch pad debug 0 reg:
1751+ */
1752+#define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
1753+/*
1754+ * The i830 generation, in LVDS mode, defines P1 as the bit number set within
1755+ * this field (only one bit may be set).
1756+ */
1757+#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
1758+#define DPLL_FPA01_P1_POST_DIV_SHIFT 16
1759+/* i830, required in DVO non-gang */
1760+#define PLL_P2_DIVIDE_BY_4 (1 << 23)
1761+#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
1762+#define PLL_REF_INPUT_DREFCLK (0 << 13)
1763+#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
1764+#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
1765+#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
1766+#define PLL_REF_INPUT_MASK (3 << 13)
1767+#define PLL_LOAD_PULSE_PHASE_SHIFT 9
1768+/*
1769+ * Parallel to Serial Load Pulse phase selection.
1770+ * Selects the phase for the 10X DPLL clock for the PCIe
1771+ * digital display port. The range is 4 to 13; 10 or more
1772+ * is just a flip delay. The default is 6
1773+ */
1774+#define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
1775+#define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
1776+/*
1777+ * SDVO multiplier for 945G/GM. Not used on 965.
1778+ */
1779+#define SDVO_MULTIPLIER_MASK 0x000000ff
1780+#define SDVO_MULTIPLIER_SHIFT_HIRES 4
1781+#define SDVO_MULTIPLIER_SHIFT_VGA 0
1782+#define DPLL_A_MD 0x0601c /* 965+ only */
1783+/*
1784+ * UDI pixel divider, controlling how many pixels are stuffed into a packet.
1785+ *
1786+ * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
1787+ */
1788+#define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
1789+#define DPLL_MD_UDI_DIVIDER_SHIFT 24
1790+/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
1791+#define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
1792+#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
1793+/*
1794+ * SDVO/UDI pixel multiplier.
1795+ *
1796+ * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
1797+ * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
1798+ * modes, the bus rate would be below the limits, so SDVO allows for stuffing
1799+ * dummy bytes in the datastream at an increased clock rate, with both sides of
1800+ * the link knowing how many bytes are fill.
1801+ *
1802+ * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
1803+ * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
1804+ * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
1805+ * through an SDVO command.
1806+ *
1807+ * This register field has values of multiplication factor minus 1, with
1808+ * a maximum multiplier of 5 for SDVO.
1809+ */
1810+#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
1811+#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
1812+/*
1813+ * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
1814+ * This best be set to the default value (3) or the CRT won't work. No,
1815+ * I don't entirely understand what this does...
1816+ */
1817+#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
1818+#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
1819+#define DPLL_B_MD 0x06020 /* 965+ only */
1820+#define FPA0 0x06040
1821+#define FPA1 0x06044
1822+#define FPB0 0x06048
1823+#define FPB1 0x0604c
1824+#define FP_N_DIV_MASK 0x003f0000
1825+#define FP_N_DIV_SHIFT 16
1826+#define FP_M1_DIV_MASK 0x00003f00
1827+#define FP_M1_DIV_SHIFT 8
1828+#define FP_M2_DIV_MASK 0x0000003f
1829+#define FP_M2_DIV_SHIFT 0
1830+#define DPLL_TEST 0x606c
1831+#define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
1832+#define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
1833+#define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
1834+#define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
1835+#define DPLLB_TEST_N_BYPASS (1 << 19)
1836+#define DPLLB_TEST_M_BYPASS (1 << 18)
1837+#define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
1838+#define DPLLA_TEST_N_BYPASS (1 << 3)
1839+#define DPLLA_TEST_M_BYPASS (1 << 2)
1840+#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
1841+#define D_STATE 0x6104
1842+#define CG_2D_DIS 0x6200
1843+#define CG_3D_DIS 0x6204
1844+
1845+/*
1846+ * Palette regs
1847+ */
1848+
1849+#define PALETTE_A 0x0a000
1850+#define PALETTE_B 0x0a800
1851+
1852+/*
1853+ * Overlay regs
1854+ */
1855+
1856+#define OVADD 0x30000
1857+#define DOVSTA 0x30008
1858+#define OC_BUF (0x3<<20)
1859+#define OGAMC5 0x30010
1860+#define OGAMC4 0x30014
1861+#define OGAMC3 0x30018
1862+#define OGAMC2 0x3001c
1863+#define OGAMC1 0x30020
1864+#define OGAMC0 0x30024
1865+
1866+/*
1867+ * Display engine regs
1868+ */
1869+
1870+/* Pipe A timing regs */
1871+#define HTOTAL_A 0x60000
1872+#define HBLANK_A 0x60004
1873+#define HSYNC_A 0x60008
1874+#define VTOTAL_A 0x6000c
1875+#define VBLANK_A 0x60010
1876+#define VSYNC_A 0x60014
1877+#define PIPEASRC 0x6001c
1878+#define BCLRPAT_A 0x60020
1879+
1880+/* Pipe B timing regs */
1881+#define HTOTAL_B 0x61000
1882+#define HBLANK_B 0x61004
1883+#define HSYNC_B 0x61008
1884+#define VTOTAL_B 0x6100c
1885+#define VBLANK_B 0x61010
1886+#define VSYNC_B 0x61014
1887+#define PIPEBSRC 0x6101c
1888+#define BCLRPAT_B 0x61020
1889+
1890+/* VGA port control */
1891+#define ADPA 0x61100
1892+#define ADPA_DAC_ENABLE (1<<31)
1893+#define ADPA_DAC_DISABLE 0
1894+#define ADPA_PIPE_SELECT_MASK (1<<30)
1895+#define ADPA_PIPE_A_SELECT 0
1896+#define ADPA_PIPE_B_SELECT (1<<30)
1897+#define ADPA_USE_VGA_HVPOLARITY (1<<15)
1898+#define ADPA_SETS_HVPOLARITY 0
1899+#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
1900+#define ADPA_VSYNC_CNTL_ENABLE 0
1901+#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
1902+#define ADPA_HSYNC_CNTL_ENABLE 0
1903+#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
1904+#define ADPA_VSYNC_ACTIVE_LOW 0
1905+#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
1906+#define ADPA_HSYNC_ACTIVE_LOW 0
1907+#define ADPA_DPMS_MASK (~(3<<10))
1908+#define ADPA_DPMS_ON (0<<10)
1909+#define ADPA_DPMS_SUSPEND (1<<10)
1910+#define ADPA_DPMS_STANDBY (2<<10)
1911+#define ADPA_DPMS_OFF (3<<10)
1912+
1913+/* Hotplug control (945+ only) */
1914+#define PORT_HOTPLUG_EN 0x61110
1915+#define SDVOB_HOTPLUG_INT_EN (1 << 26)
1916+#define SDVOC_HOTPLUG_INT_EN (1 << 25)
1917+#define TV_HOTPLUG_INT_EN (1 << 18)
1918+#define CRT_HOTPLUG_INT_EN (1 << 9)
1919+#define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
1920+
1921+#define PORT_HOTPLUG_STAT 0x61114
1922+#define CRT_HOTPLUG_INT_STATUS (1 << 11)
1923+#define TV_HOTPLUG_INT_STATUS (1 << 10)
1924+#define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
1925+#define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
1926+#define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
1927+#define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
1928+#define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
1929+#define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
1930+
1931+/* SDVO port control */
1932+#define SDVOB 0x61140
1933+#define SDVOC 0x61160
1934+#define SDVO_ENABLE (1 << 31)
1935+#define SDVO_PIPE_B_SELECT (1 << 30)
1936+#define SDVO_STALL_SELECT (1 << 29)
1937+#define SDVO_INTERRUPT_ENABLE (1 << 26)
1938+/**
1939+ * 915G/GM SDVO pixel multiplier.
1940+ *
1941+ * Programmed value is multiplier - 1, up to 5x.
1942+ *
1943+ * \sa DPLL_MD_UDI_MULTIPLIER_MASK
1944+ */
1945+#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
1946+#define SDVO_PORT_MULTIPLY_SHIFT 23
1947+#define SDVO_PHASE_SELECT_MASK (15 << 19)
1948+#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
1949+#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
1950+#define SDVOC_GANG_MODE (1 << 16)
1951+#define SDVO_BORDER_ENABLE (1 << 7)
1952+#define SDVOB_PCIE_CONCURRENCY (1 << 3)
1953+#define SDVO_DETECTED (1 << 2)
1954+/* Bits to be preserved when writing */
1955+#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26))
1956+#define SDVOC_PRESERVE_MASK ((1 << 17) | (1 << 26))
1957+
1958+/* DVO port control */
1959+#define DVOA 0x61120
1960+#define DVOB 0x61140
1961+#define DVOC 0x61160
1962+#define DVO_ENABLE (1 << 31)
1963+#define DVO_PIPE_B_SELECT (1 << 30)
1964+#define DVO_PIPE_STALL_UNUSED (0 << 28)
1965+#define DVO_PIPE_STALL (1 << 28)
1966+#define DVO_PIPE_STALL_TV (2 << 28)
1967+#define DVO_PIPE_STALL_MASK (3 << 28)
1968+#define DVO_USE_VGA_SYNC (1 << 15)
1969+#define DVO_DATA_ORDER_I740 (0 << 14)
1970+#define DVO_DATA_ORDER_FP (1 << 14)
1971+#define DVO_VSYNC_DISABLE (1 << 11)
1972+#define DVO_HSYNC_DISABLE (1 << 10)
1973+#define DVO_VSYNC_TRISTATE (1 << 9)
1974+#define DVO_HSYNC_TRISTATE (1 << 8)
1975+#define DVO_BORDER_ENABLE (1 << 7)
1976+#define DVO_DATA_ORDER_GBRG (1 << 6)
1977+#define DVO_DATA_ORDER_RGGB (0 << 6)
1978+#define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6)
1979+#define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6)
1980+#define DVO_VSYNC_ACTIVE_HIGH (1 << 4)
1981+#define DVO_HSYNC_ACTIVE_HIGH (1 << 3)
1982+#define DVO_BLANK_ACTIVE_HIGH (1 << 2)
1983+#define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */
1984+#define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */
1985+#define DVO_PRESERVE_MASK (0x7<<24)
1986+#define DVOA_SRCDIM 0x61124
1987+#define DVOB_SRCDIM 0x61144
1988+#define DVOC_SRCDIM 0x61164
1989+#define DVO_SRCDIM_HORIZONTAL_SHIFT 12
1990+#define DVO_SRCDIM_VERTICAL_SHIFT 0
1991+
1992+/* LVDS port control */
1993+#define LVDS 0x61180
1994+/*
1995+ * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
1996+ * the DPLL semantics change when the LVDS is assigned to that pipe.
1997+ */
1998+#define LVDS_PORT_EN (1 << 31)
1999+/* Selects pipe B for LVDS data. Must be set on pre-965. */
2000+#define LVDS_PIPEB_SELECT (1 << 30)
2001+/*
2002+ * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
2003+ * pixel.
2004+ */
2005+#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
2006+#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
2007+#define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
2008+/*
2009+ * Controls the A3 data pair, which contains the additional LSBs for 24 bit
2010+ * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
2011+ * on.
2012+ */
2013+#define LVDS_A3_POWER_MASK (3 << 6)
2014+#define LVDS_A3_POWER_DOWN (0 << 6)
2015+#define LVDS_A3_POWER_UP (3 << 6)
2016+/*
2017+ * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
2018+ * is set.
2019+ */
2020+#define LVDS_CLKB_POWER_MASK (3 << 4)
2021+#define LVDS_CLKB_POWER_DOWN (0 << 4)
2022+#define LVDS_CLKB_POWER_UP (3 << 4)
2023+/*
2024+ * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
2025+ * setting for whether we are in dual-channel mode. The B3 pair will
2026+ * additionally only be powered up when LVDS_A3_POWER_UP is set.
2027+ */
2028+#define LVDS_B0B3_POWER_MASK (3 << 2)
2029+#define LVDS_B0B3_POWER_DOWN (0 << 2)
2030+#define LVDS_B0B3_POWER_UP (3 << 2)
2031+
2032+/* Panel power sequencing */
2033+#define PP_STATUS 0x61200
2034+#define PP_ON (1 << 31)
2035+/*
2036+ * Indicates that all dependencies of the panel are on:
2037+ *
2038+ * - PLL enabled
2039+ * - pipe enabled
2040+ * - LVDS/DVOB/DVOC on
2041+ */
2042+#define PP_READY (1 << 30)
2043+#define PP_SEQUENCE_NONE (0 << 28)
2044+#define PP_SEQUENCE_ON (1 << 28)
2045+#define PP_SEQUENCE_OFF (2 << 28)
2046+#define PP_SEQUENCE_MASK 0x30000000
2047+#define PP_CONTROL 0x61204
2048+#define POWER_TARGET_ON (1 << 0)
2049+#define PP_ON_DELAYS 0x61208
2050+#define PP_OFF_DELAYS 0x6120c
2051+#define PP_DIVISOR 0x61210
2052+
2053+/* Panel fitting */
2054+#define PFIT_CONTROL 0x61230
2055+#define PFIT_ENABLE (1 << 31)
2056+#define PFIT_PIPE_MASK (3 << 29)
2057+#define PFIT_PIPE_SHIFT 29
2058+#define VERT_INTERP_DISABLE (0 << 10)
2059+#define VERT_INTERP_BILINEAR (1 << 10)
2060+#define VERT_INTERP_MASK (3 << 10)
2061+#define VERT_AUTO_SCALE (1 << 9)
2062+#define HORIZ_INTERP_DISABLE (0 << 6)
2063+#define HORIZ_INTERP_BILINEAR (1 << 6)
2064+#define HORIZ_INTERP_MASK (3 << 6)
2065+#define HORIZ_AUTO_SCALE (1 << 5)
2066+#define PANEL_8TO6_DITHER_ENABLE (1 << 3)
2067+#define PFIT_PGM_RATIOS 0x61234
2068+#define PFIT_VERT_SCALE_MASK 0xfff00000
2069+#define PFIT_HORIZ_SCALE_MASK 0x0000fff0
2070+#define PFIT_AUTO_RATIOS 0x61238
2071+
2072+/* Backlight control */
2073+#define BLC_PWM_CTL 0x61254
2074+#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
2075+#define BLC_PWM_CTL2 0x61250 /* 965+ only */
2076+/*
2077+ * This is the most significant 15 bits of the number of backlight cycles in a
2078+ * complete cycle of the modulated backlight control.
2079+ *
2080+ * The actual value is this field multiplied by two.
2081+ */
2082+#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
2083+#define BLM_LEGACY_MODE (1 << 16)
2084+/*
2085+ * This is the number of cycles out of the backlight modulation cycle for which
2086+ * the backlight is on.
2087+ *
2088+ * This field must be no greater than the number of cycles in the complete
2089+ * backlight modulation cycle.
2090+ */
2091+#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
2092+#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
2093+
2094+/* TV port control */
2095+#define TV_CTL 0x68000
2096+/** Enables the TV encoder */
2097+# define TV_ENC_ENABLE (1 << 31)
2098+/** Sources the TV encoder input from pipe B instead of A. */
2099+# define TV_ENC_PIPEB_SELECT (1 << 30)
2100+/** Outputs composite video (DAC A only) */
2101+# define TV_ENC_OUTPUT_COMPOSITE (0 << 28)
2102+/** Outputs SVideo video (DAC B/C) */
2103+# define TV_ENC_OUTPUT_SVIDEO (1 << 28)
2104+/** Outputs Component video (DAC A/B/C) */
2105+# define TV_ENC_OUTPUT_COMPONENT (2 << 28)
2106+/** Outputs Composite and SVideo (DAC A/B/C) */
2107+# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28)
2108+# define TV_TRILEVEL_SYNC (1 << 21)
2109+/** Enables slow sync generation (945GM only) */
2110+# define TV_SLOW_SYNC (1 << 20)
2111+/** Selects 4x oversampling for 480i and 576p */
2112+# define TV_OVERSAMPLE_4X (0 << 18)
2113+/** Selects 2x oversampling for 720p and 1080i */
2114+# define TV_OVERSAMPLE_2X (1 << 18)
2115+/** Selects no oversampling for 1080p */
2116+# define TV_OVERSAMPLE_NONE (2 << 18)
2117+/** Selects 8x oversampling */
2118+# define TV_OVERSAMPLE_8X (3 << 18)
2119+/** Selects progressive mode rather than interlaced */
2120+# define TV_PROGRESSIVE (1 << 17)
2121+/** Sets the colorburst to PAL mode. Required for non-M PAL modes. */
2122+# define TV_PAL_BURST (1 << 16)
2123+/** Field for setting delay of Y compared to C */
2124+# define TV_YC_SKEW_MASK (7 << 12)
2125+/** Enables a fix for 480p/576p standard definition modes on the 915GM only */
2126+# define TV_ENC_SDP_FIX (1 << 11)
2127+/**
2128+ * Enables a fix for the 915GM only.
2129+ *
2130+ * Not sure what it does.
2131+ */
2132+# define TV_ENC_C0_FIX (1 << 10)
2133+/** Bits that must be preserved by software */
2134+# define TV_CTL_SAVE ((3 << 8) | (3 << 6))
2135+# define TV_FUSE_STATE_MASK (3 << 4)
2136+/** Read-only state that reports all features enabled */
2137+# define TV_FUSE_STATE_ENABLED (0 << 4)
2138+/** Read-only state that reports that Macrovision is disabled in hardware*/
2139+# define TV_FUSE_STATE_NO_MACROVISION (1 << 4)
2140+/** Read-only state that reports that TV-out is disabled in hardware. */
2141+# define TV_FUSE_STATE_DISABLED (2 << 4)
2142+/** Normal operation */
2143+# define TV_TEST_MODE_NORMAL (0 << 0)
2144+/** Encoder test pattern 1 - combo pattern */
2145+# define TV_TEST_MODE_PATTERN_1 (1 << 0)
2146+/** Encoder test pattern 2 - full screen vertical 75% color bars */
2147+# define TV_TEST_MODE_PATTERN_2 (2 << 0)
2148+/** Encoder test pattern 3 - full screen horizontal 75% color bars */
2149+# define TV_TEST_MODE_PATTERN_3 (3 << 0)
2150+/** Encoder test pattern 4 - random noise */
2151+# define TV_TEST_MODE_PATTERN_4 (4 << 0)
2152+/** Encoder test pattern 5 - linear color ramps */
2153+# define TV_TEST_MODE_PATTERN_5 (5 << 0)
2154+/**
2155+ * This test mode forces the DACs to 50% of full output.
2156+ *
2157+ * This is used for load detection in combination with TVDAC_SENSE_MASK
2158+ */
2159+# define TV_TEST_MODE_MONITOR_DETECT (7 << 0)
2160+# define TV_TEST_MODE_MASK (7 << 0)
2161+
2162+#define TV_DAC 0x68004
2163+/**
2164+ * Reports that DAC state change logic has reported change (RO).
2165+ *
2166+ * This gets cleared when TV_DAC_STATE_EN is cleared
2167+*/
2168+# define TVDAC_STATE_CHG (1 << 31)
2169+# define TVDAC_SENSE_MASK (7 << 28)
2170+/** Reports that DAC A voltage is above the detect threshold */
2171+# define TVDAC_A_SENSE (1 << 30)
2172+/** Reports that DAC B voltage is above the detect threshold */
2173+# define TVDAC_B_SENSE (1 << 29)
2174+/** Reports that DAC C voltage is above the detect threshold */
2175+# define TVDAC_C_SENSE (1 << 28)
2176+/**
2177+ * Enables DAC state detection logic, for load-based TV detection.
2178+ *
2179+ * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set
2180+ * to off, for load detection to work.
2181+ */
2182+# define TVDAC_STATE_CHG_EN (1 << 27)
2183+/** Sets the DAC A sense value to high */
2184+# define TVDAC_A_SENSE_CTL (1 << 26)
2185+/** Sets the DAC B sense value to high */
2186+# define TVDAC_B_SENSE_CTL (1 << 25)
2187+/** Sets the DAC C sense value to high */
2188+# define TVDAC_C_SENSE_CTL (1 << 24)
2189+/** Overrides the ENC_ENABLE and DAC voltage levels */
2190+# define DAC_CTL_OVERRIDE (1 << 7)
2191+/** Sets the slew rate. Must be preserved in software */
2192+# define ENC_TVDAC_SLEW_FAST (1 << 6)
2193+# define DAC_A_1_3_V (0 << 4)
2194+# define DAC_A_1_1_V (1 << 4)
2195+# define DAC_A_0_7_V (2 << 4)
2196+# define DAC_A_OFF (3 << 4)
2197+# define DAC_B_1_3_V (0 << 2)
2198+# define DAC_B_1_1_V (1 << 2)
2199+# define DAC_B_0_7_V (2 << 2)
2200+# define DAC_B_OFF (3 << 2)
2201+# define DAC_C_1_3_V (0 << 0)
2202+# define DAC_C_1_1_V (1 << 0)
2203+# define DAC_C_0_7_V (2 << 0)
2204+# define DAC_C_OFF (3 << 0)
2205+
2206+/**
2207+ * CSC coefficients are stored in a floating point format with 9 bits of
2208+ * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n,
2209+ * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with
2210+ * -1 (0x3) being the only legal negative value.
2211+ */
2212+#define TV_CSC_Y 0x68010
2213+# define TV_RY_MASK 0x07ff0000
2214+# define TV_RY_SHIFT 16
2215+# define TV_GY_MASK 0x00000fff
2216+# define TV_GY_SHIFT 0
2217+
2218+#define TV_CSC_Y2 0x68014
2219+# define TV_BY_MASK 0x07ff0000
2220+# define TV_BY_SHIFT 16
2221+/**
2222+ * Y attenuation for component video.
2223+ *
2224+ * Stored in 1.9 fixed point.
2225+ */
2226+# define TV_AY_MASK 0x000003ff
2227+# define TV_AY_SHIFT 0
2228+
2229+#define TV_CSC_U 0x68018
2230+# define TV_RU_MASK 0x07ff0000
2231+# define TV_RU_SHIFT 16
2232+# define TV_GU_MASK 0x000007ff
2233+# define TV_GU_SHIFT 0
2234+
2235+#define TV_CSC_U2 0x6801c
2236+# define TV_BU_MASK 0x07ff0000
2237+# define TV_BU_SHIFT 16
2238+/**
2239+ * U attenuation for component video.
2240+ *
2241+ * Stored in 1.9 fixed point.
2242+ */
2243+# define TV_AU_MASK 0x000003ff
2244+# define TV_AU_SHIFT 0
2245+
2246+#define TV_CSC_V 0x68020
2247+# define TV_RV_MASK 0x0fff0000
2248+# define TV_RV_SHIFT 16
2249+# define TV_GV_MASK 0x000007ff
2250+# define TV_GV_SHIFT 0
2251+
2252+#define TV_CSC_V2 0x68024
2253+# define TV_BV_MASK 0x07ff0000
2254+# define TV_BV_SHIFT 16
2255+/**
2256+ * V attenuation for component video.
2257+ *
2258+ * Stored in 1.9 fixed point.
2259+ */
2260+# define TV_AV_MASK 0x000007ff
2261+# define TV_AV_SHIFT 0
2262+
2263+#define TV_CLR_KNOBS 0x68028
2264+/** 2s-complement brightness adjustment */
2265+# define TV_BRIGHTNESS_MASK 0xff000000
2266+# define TV_BRIGHTNESS_SHIFT 24
2267+/** Contrast adjustment, as a 2.6 unsigned floating point number */
2268+# define TV_CONTRAST_MASK 0x00ff0000
2269+# define TV_CONTRAST_SHIFT 16
2270+/** Saturation adjustment, as a 2.6 unsigned floating point number */
2271+# define TV_SATURATION_MASK 0x0000ff00
2272+# define TV_SATURATION_SHIFT 8
2273+/** Hue adjustment, as an integer phase angle in degrees */
2274+# define TV_HUE_MASK 0x000000ff
2275+# define TV_HUE_SHIFT 0
2276+
2277+#define TV_CLR_LEVEL 0x6802c
2278+/** Controls the DAC level for black */
2279+# define TV_BLACK_LEVEL_MASK 0x01ff0000
2280+# define TV_BLACK_LEVEL_SHIFT 16
2281+/** Controls the DAC level for blanking */
2282+# define TV_BLANK_LEVEL_MASK 0x000001ff
2283+# define TV_BLANK_LEVEL_SHIFT 0
2284+
2285+#define TV_H_CTL_1 0x68030
2286+/** Number of pixels in the hsync. */
2287+# define TV_HSYNC_END_MASK 0x1fff0000
2288+# define TV_HSYNC_END_SHIFT 16
2289+/** Total number of pixels minus one in the line (display and blanking). */
2290+# define TV_HTOTAL_MASK 0x00001fff
2291+# define TV_HTOTAL_SHIFT 0
2292+
2293+#define TV_H_CTL_2 0x68034
2294+/** Enables the colorburst (needed for non-component color) */
2295+# define TV_BURST_ENA (1 << 31)
2296+/** Offset of the colorburst from the start of hsync, in pixels minus one. */
2297+# define TV_HBURST_START_SHIFT 16
2298+# define TV_HBURST_START_MASK 0x1fff0000
2299+/** Length of the colorburst */
2300+# define TV_HBURST_LEN_SHIFT 0
2301+# define TV_HBURST_LEN_MASK 0x0001fff
2302+
2303+#define TV_H_CTL_3 0x68038
2304+/** End of hblank, measured in pixels minus one from start of hsync */
2305+# define TV_HBLANK_END_SHIFT 16
2306+# define TV_HBLANK_END_MASK 0x1fff0000
2307+/** Start of hblank, measured in pixels minus one from start of hsync */
2308+# define TV_HBLANK_START_SHIFT 0
2309+# define TV_HBLANK_START_MASK 0x0001fff
2310+
2311+#define TV_V_CTL_1 0x6803c
2312+/** XXX */
2313+# define TV_NBR_END_SHIFT 16
2314+# define TV_NBR_END_MASK 0x07ff0000
2315+/** XXX */
2316+# define TV_VI_END_F1_SHIFT 8
2317+# define TV_VI_END_F1_MASK 0x00003f00
2318+/** XXX */
2319+# define TV_VI_END_F2_SHIFT 0
2320+# define TV_VI_END_F2_MASK 0x0000003f
2321+
2322+#define TV_V_CTL_2 0x68040
2323+/** Length of vsync, in half lines */
2324+# define TV_VSYNC_LEN_MASK 0x07ff0000
2325+# define TV_VSYNC_LEN_SHIFT 16
2326+/** Offset of the start of vsync in field 1, measured in one less than the
2327+ * number of half lines.
2328+ */
2329+# define TV_VSYNC_START_F1_MASK 0x00007f00
2330+# define TV_VSYNC_START_F1_SHIFT 8
2331+/**
2332+ * Offset of the start of vsync in field 2, measured in one less than the
2333+ * number of half lines.
2334+ */
2335+# define TV_VSYNC_START_F2_MASK 0x0000007f
2336+# define TV_VSYNC_START_F2_SHIFT 0
2337+
2338+#define TV_V_CTL_3 0x68044
2339+/** Enables generation of the equalization signal */
2340+# define TV_EQUAL_ENA (1 << 31)
2341+/** Length of vsync, in half lines */
2342+# define TV_VEQ_LEN_MASK 0x007f0000
2343+# define TV_VEQ_LEN_SHIFT 16
2344+/** Offset of the start of equalization in field 1, measured in one less than
2345+ * the number of half lines.
2346+ */
2347+# define TV_VEQ_START_F1_MASK 0x0007f00
2348+# define TV_VEQ_START_F1_SHIFT 8
2349+/**
2350+ * Offset of the start of equalization in field 2, measured in one less than
2351+ * the number of half lines.
2352+ */
2353+# define TV_VEQ_START_F2_MASK 0x000007f
2354+# define TV_VEQ_START_F2_SHIFT 0
2355+
2356+#define TV_V_CTL_4 0x68048
2357+/**
2358+ * Offset to start of vertical colorburst, measured in one less than the
2359+ * number of lines from vertical start.
2360+ */
2361+# define TV_VBURST_START_F1_MASK 0x003f0000
2362+# define TV_VBURST_START_F1_SHIFT 16
2363+/**
2364+ * Offset to the end of vertical colorburst, measured in one less than the
2365+ * number of lines from the start of NBR.
2366+ */
2367+# define TV_VBURST_END_F1_MASK 0x000000ff
2368+# define TV_VBURST_END_F1_SHIFT 0
2369+
2370+#define TV_V_CTL_5 0x6804c
2371+/**
2372+ * Offset to start of vertical colorburst, measured in one less than the
2373+ * number of lines from vertical start.
2374+ */
2375+# define TV_VBURST_START_F2_MASK 0x003f0000
2376+# define TV_VBURST_START_F2_SHIFT 16
2377+/**
2378+ * Offset to the end of vertical colorburst, measured in one less than the
2379+ * number of lines from the start of NBR.
2380+ */
2381+# define TV_VBURST_END_F2_MASK 0x000000ff
2382+# define TV_VBURST_END_F2_SHIFT 0
2383+
2384+#define TV_V_CTL_6 0x68050
2385+/**
2386+ * Offset to start of vertical colorburst, measured in one less than the
2387+ * number of lines from vertical start.
2388+ */
2389+# define TV_VBURST_START_F3_MASK 0x003f0000
2390+# define TV_VBURST_START_F3_SHIFT 16
2391+/**
2392+ * Offset to the end of vertical colorburst, measured in one less than the
2393+ * number of lines from the start of NBR.
2394+ */
2395+# define TV_VBURST_END_F3_MASK 0x000000ff
2396+# define TV_VBURST_END_F3_SHIFT 0
2397+
2398+#define TV_V_CTL_7 0x68054
2399+/**
2400+ * Offset to start of vertical colorburst, measured in one less than the
2401+ * number of lines from vertical start.
2402+ */
2403+# define TV_VBURST_START_F4_MASK 0x003f0000
2404+# define TV_VBURST_START_F4_SHIFT 16
2405+/**
2406+ * Offset to the end of vertical colorburst, measured in one less than the
2407+ * number of lines from the start of NBR.
2408+ */
2409+# define TV_VBURST_END_F4_MASK 0x000000ff
2410+# define TV_VBURST_END_F4_SHIFT 0
2411+
2412+#define TV_SC_CTL_1 0x68060
2413+/** Turns on the first subcarrier phase generation DDA */
2414+# define TV_SC_DDA1_EN (1 << 31)
2415+/** Turns on the first subcarrier phase generation DDA */
2416+# define TV_SC_DDA2_EN (1 << 30)
2417+/** Turns on the first subcarrier phase generation DDA */
2418+# define TV_SC_DDA3_EN (1 << 29)
2419+/** Sets the subcarrier DDA to reset frequency every other field */
2420+# define TV_SC_RESET_EVERY_2 (0 << 24)
2421+/** Sets the subcarrier DDA to reset frequency every fourth field */
2422+# define TV_SC_RESET_EVERY_4 (1 << 24)
2423+/** Sets the subcarrier DDA to reset frequency every eighth field */
2424+# define TV_SC_RESET_EVERY_8 (2 << 24)
2425+/** Sets the subcarrier DDA to never reset the frequency */
2426+# define TV_SC_RESET_NEVER (3 << 24)
2427+/** Sets the peak amplitude of the colorburst.*/
2428+# define TV_BURST_LEVEL_MASK 0x00ff0000
2429+# define TV_BURST_LEVEL_SHIFT 16
2430+/** Sets the increment of the first subcarrier phase generation DDA */
2431+# define TV_SCDDA1_INC_MASK 0x00000fff
2432+# define TV_SCDDA1_INC_SHIFT 0
2433+
2434+#define TV_SC_CTL_2 0x68064
2435+/** Sets the rollover for the second subcarrier phase generation DDA */
2436+# define TV_SCDDA2_SIZE_MASK 0x7fff0000
2437+# define TV_SCDDA2_SIZE_SHIFT 16
2438+/** Sets the increent of the second subcarrier phase generation DDA */
2439+# define TV_SCDDA2_INC_MASK 0x00007fff
2440+# define TV_SCDDA2_INC_SHIFT 0
2441+
2442+#define TV_SC_CTL_3 0x68068
2443+/** Sets the rollover for the third subcarrier phase generation DDA */
2444+# define TV_SCDDA3_SIZE_MASK 0x7fff0000
2445+# define TV_SCDDA3_SIZE_SHIFT 16
2446+/** Sets the increent of the third subcarrier phase generation DDA */
2447+# define TV_SCDDA3_INC_MASK 0x00007fff
2448+# define TV_SCDDA3_INC_SHIFT 0
2449+
2450+#define TV_WIN_POS 0x68070
2451+/** X coordinate of the display from the start of horizontal active */
2452+# define TV_XPOS_MASK 0x1fff0000
2453+# define TV_XPOS_SHIFT 16
2454+/** Y coordinate of the display from the start of vertical active (NBR) */
2455+# define TV_YPOS_MASK 0x00000fff
2456+# define TV_YPOS_SHIFT 0
2457+
2458+#define TV_WIN_SIZE 0x68074
2459+/** Horizontal size of the display window, measured in pixels*/
2460+# define TV_XSIZE_MASK 0x1fff0000
2461+# define TV_XSIZE_SHIFT 16
2462+/**
2463+ * Vertical size of the display window, measured in pixels.
2464+ *
2465+ * Must be even for interlaced modes.
2466+ */
2467+# define TV_YSIZE_MASK 0x00000fff
2468+# define TV_YSIZE_SHIFT 0
2469+
2470+#define TV_FILTER_CTL_1 0x68080
2471+/**
2472+ * Enables automatic scaling calculation.
2473+ *
2474+ * If set, the rest of the registers are ignored, and the calculated values can
2475+ * be read back from the register.
2476+ */
2477+# define TV_AUTO_SCALE (1 << 31)
2478+/**
2479+ * Disables the vertical filter.
2480+ *
2481+ * This is required on modes more than 1024 pixels wide */
2482+# define TV_V_FILTER_BYPASS (1 << 29)
2483+/** Enables adaptive vertical filtering */
2484+# define TV_VADAPT (1 << 28)
2485+# define TV_VADAPT_MODE_MASK (3 << 26)
2486+/** Selects the least adaptive vertical filtering mode */
2487+# define TV_VADAPT_MODE_LEAST (0 << 26)
2488+/** Selects the moderately adaptive vertical filtering mode */
2489+# define TV_VADAPT_MODE_MODERATE (1 << 26)
2490+/** Selects the most adaptive vertical filtering mode */
2491+# define TV_VADAPT_MODE_MOST (3 << 26)
2492+/**
2493+ * Sets the horizontal scaling factor.
2494+ *
2495+ * This should be the fractional part of the horizontal scaling factor divided
2496+ * by the oversampling rate. TV_HSCALE should be less than 1, and set to:
2497+ *
2498+ * (src width - 1) / ((oversample * dest width) - 1)
2499+ */
2500+# define TV_HSCALE_FRAC_MASK 0x00003fff
2501+# define TV_HSCALE_FRAC_SHIFT 0
2502+
2503+#define TV_FILTER_CTL_2 0x68084
2504+/**
2505+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
2506+ *
2507+ * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1)
2508+ */
2509+# define TV_VSCALE_INT_MASK 0x00038000
2510+# define TV_VSCALE_INT_SHIFT 15
2511+/**
2512+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
2513+ *
2514+ * \sa TV_VSCALE_INT_MASK
2515+ */
2516+# define TV_VSCALE_FRAC_MASK 0x00007fff
2517+# define TV_VSCALE_FRAC_SHIFT 0
2518+
2519+#define TV_FILTER_CTL_3 0x68088
2520+/**
2521+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
2522+ *
2523+ * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1))
2524+ *
2525+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
2526+ */
2527+# define TV_VSCALE_IP_INT_MASK 0x00038000
2528+# define TV_VSCALE_IP_INT_SHIFT 15
2529+/**
2530+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
2531+ *
2532+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
2533+ *
2534+ * \sa TV_VSCALE_IP_INT_MASK
2535+ */
2536+# define TV_VSCALE_IP_FRAC_MASK 0x00007fff
2537+# define TV_VSCALE_IP_FRAC_SHIFT 0
2538+
2539+#define TV_CC_CONTROL 0x68090
2540+# define TV_CC_ENABLE (1 << 31)
2541+/**
2542+ * Specifies which field to send the CC data in.
2543+ *
2544+ * CC data is usually sent in field 0.
2545+ */
2546+# define TV_CC_FID_MASK (1 << 27)
2547+# define TV_CC_FID_SHIFT 27
2548+/** Sets the horizontal position of the CC data. Usually 135. */
2549+# define TV_CC_HOFF_MASK 0x03ff0000
2550+# define TV_CC_HOFF_SHIFT 16
2551+/** Sets the vertical position of the CC data. Usually 21 */
2552+# define TV_CC_LINE_MASK 0x0000003f
2553+# define TV_CC_LINE_SHIFT 0
2554+
2555+#define TV_CC_DATA 0x68094
2556+# define TV_CC_RDY (1 << 31)
2557+/** Second word of CC data to be transmitted. */
2558+# define TV_CC_DATA_2_MASK 0x007f0000
2559+# define TV_CC_DATA_2_SHIFT 16
2560+/** First word of CC data to be transmitted. */
2561+# define TV_CC_DATA_1_MASK 0x0000007f
2562+# define TV_CC_DATA_1_SHIFT 0
2563+
2564+#define TV_H_LUMA_0 0x68100
2565+#define TV_H_LUMA_59 0x681ec
2566+#define TV_H_CHROMA_0 0x68200
2567+#define TV_H_CHROMA_59 0x682ec
2568+#define TV_V_LUMA_0 0x68300
2569+#define TV_V_LUMA_42 0x683a8
2570+#define TV_V_CHROMA_0 0x68400
2571+#define TV_V_CHROMA_42 0x684a8
2572+
2573+/* Display & cursor control */
2574+
2575+/* Pipe A */
2576+#define PIPEADSL 0x70000
2577+#define PIPEACONF 0x70008
2578+#define PIPEACONF_ENABLE (1<<31)
2579+#define PIPEACONF_DISABLE 0
2580+#define PIPEACONF_DOUBLE_WIDE (1<<30)
2581+#define I965_PIPECONF_ACTIVE (1<<30)
2582+#define PIPEACONF_SINGLE_WIDE 0
2583+#define PIPEACONF_PIPE_UNLOCKED 0
2584+#define PIPEACONF_PIPE_LOCKED (1<<25)
2585+#define PIPEACONF_PALETTE 0
2586+#define PIPEACONF_GAMMA (1<<24)
2587+#define PIPECONF_FORCE_BORDER (1<<25)
2588+#define PIPECONF_PROGRESSIVE (0 << 21)
2589+#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
2590+#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
2591+#define PIPEASTAT 0x70024
2592+#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31)
2593+#define PIPE_CRC_ERROR_ENABLE (1UL<<29)
2594+#define PIPE_CRC_DONE_ENABLE (1UL<<28)
2595+#define PIPE_GMBUS_EVENT_ENABLE (1UL<<27)
2596+#define PIPE_HOTPLUG_INTERRUPT_ENABLE (1UL<<26)
2597+#define PIPE_VSYNC_INTERRUPT_ENABLE (1UL<<25)
2598+#define PIPE_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
2599+#define PIPE_DPST_EVENT_ENABLE (1UL<<23)
2600+#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
2601+#define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
2602+#define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
2603+#define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */
2604+#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
2605+#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17)
2606+#define PIPE_OVERLAY_UPDATED_ENABLE (1UL<<16)
2607+#define PIPE_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
2608+#define PIPE_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
2609+#define PIPE_GMBUS_INTERRUPT_STATUS (1UL<<11)
2610+#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10)
2611+#define PIPE_VSYNC_INTERRUPT_STATUS (1UL<<9)
2612+#define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
2613+#define PIPE_DPST_EVENT_STATUS (1UL<<7)
2614+#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6)
2615+#define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
2616+#define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
2617+#define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */
2618+#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
2619+#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
2620+#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0)
2621+
2622+#define DSPARB 0x70030
2623+#define DSPARB_CSTART_MASK (0x7f << 7)
2624+#define DSPARB_CSTART_SHIFT 7
2625+#define DSPARB_BSTART_MASK (0x7f)
2626+#define DSPARB_BSTART_SHIFT 0
2627+/*
2628+ * The two pipe frame counter registers are not synchronized, so
2629+ * reading a stable value is somewhat tricky. The following code
2630+ * should work:
2631+ *
2632+ * do {
2633+ * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
2634+ * PIPE_FRAME_HIGH_SHIFT;
2635+ * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >>
2636+ * PIPE_FRAME_LOW_SHIFT);
2637+ * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
2638+ * PIPE_FRAME_HIGH_SHIFT);
2639+ * } while (high1 != high2);
2640+ * frame = (high1 << 8) | low1;
2641+ */
2642+#define PIPEAFRAMEHIGH 0x70040
2643+#define PIPE_FRAME_HIGH_MASK 0x0000ffff
2644+#define PIPE_FRAME_HIGH_SHIFT 0
2645+#define PIPEAFRAMEPIXEL 0x70044
2646+#define PIPE_FRAME_LOW_MASK 0xff000000
2647+#define PIPE_FRAME_LOW_SHIFT 24
2648+#define PIPE_PIXEL_MASK 0x00ffffff
2649+#define PIPE_PIXEL_SHIFT 0
2650+
2651+/* Cursor A & B regs */
2652+#define CURACNTR 0x70080
2653+#define CURSOR_MODE_DISABLE 0x00
2654+#define CURSOR_MODE_64_32B_AX 0x07
2655+#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
2656+#define MCURSOR_GAMMA_ENABLE (1 << 26)
2657+#define CURABASE 0x70084
2658+#define CURAPOS 0x70088
2659+#define CURSOR_POS_MASK 0x007FF
2660+#define CURSOR_POS_SIGN 0x8000
2661+#define CURSOR_X_SHIFT 0
2662+#define CURSOR_Y_SHIFT 16
2663+#define CURBCNTR 0x700c0
2664+#define CURBBASE 0x700c4
2665+#define CURBPOS 0x700c8
2666+
2667+/* Display A control */
2668+#define DSPACNTR 0x70180
2669+#define DISPLAY_PLANE_ENABLE (1<<31)
2670+#define DISPLAY_PLANE_DISABLE 0
2671+#define DISPPLANE_GAMMA_ENABLE (1<<30)
2672+#define DISPPLANE_GAMMA_DISABLE 0
2673+#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
2674+#define DISPPLANE_8BPP (0x2<<26)
2675+#define DISPPLANE_15_16BPP (0x4<<26)
2676+#define DISPPLANE_16BPP (0x5<<26)
2677+#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
2678+#define DISPPLANE_32BPP (0x7<<26)
2679+#define DISPPLANE_STEREO_ENABLE (1<<25)
2680+#define DISPPLANE_STEREO_DISABLE 0
2681+#define DISPPLANE_SEL_PIPE_MASK (1<<24)
2682+#define DISPPLANE_SEL_PIPE_A 0
2683+#define DISPPLANE_SEL_PIPE_B (1<<24)
2684+#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
2685+#define DISPPLANE_SRC_KEY_DISABLE 0
2686+#define DISPPLANE_LINE_DOUBLE (1<<20)
2687+#define DISPPLANE_NO_LINE_DOUBLE 0
2688+#define DISPPLANE_STEREO_POLARITY_FIRST 0
2689+#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
2690+#define DSPAADDR 0x70184
2691+#define DSPASTRIDE 0x70188
2692+#define DSPAPOS 0x7018C /* reserved */
2693+#define DSPASIZE 0x70190
2694+#define DSPASURF 0x7019C /* 965+ only */
2695+#define DSPATILEOFF 0x701A4 /* 965+ only */
2696+
2697+/* VBIOS flags */
2698+#define SWF00 0x71410
2699+#define SWF01 0x71414
2700+#define SWF02 0x71418
2701+#define SWF03 0x7141c
2702+#define SWF04 0x71420
2703+#define SWF05 0x71424
2704+#define SWF06 0x71428
2705+#define SWF10 0x70410
2706+#define SWF11 0x70414
2707+#define SWF14 0x71420
2708+#define SWF30 0x72414
2709+#define SWF31 0x72418
2710+#define SWF32 0x7241c
2711+
2712+/* Pipe B */
2713+#define PIPEBDSL 0x71000
2714+#define PIPEBCONF 0x71008
2715+#define PIPEBSTAT 0x71024
2716+#define PIPEBFRAMEHIGH 0x71040
2717+#define PIPEBFRAMEPIXEL 0x71044
2718+
2719+/* Display B control */
2720+#define DSPBCNTR 0x71180
2721+#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
2722+#define DISPPLANE_ALPHA_TRANS_DISABLE 0
2723+#define DISPPLANE_SPRITE_ABOVE_DISPLAY 0
2724+#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
2725+#define DSPBADDR 0x71184
2726+#define DSPBSTRIDE 0x71188
2727+#define DSPBPOS 0x7118C
2728+#define DSPBSIZE 0x71190
2729+#define DSPBSURF 0x7119C
2730+#define DSPBTILEOFF 0x711A4
2731+
2732+/* VBIOS regs */
2733+#define VGACNTRL 0x71400
2734+# define VGA_DISP_DISABLE (1 << 31)
2735+# define VGA_2X_MODE (1 << 30)
2736+# define VGA_PIPE_B_SELECT (1 << 29)
2737+
2738+#endif /* _I915_REG_H_ */
2739
diff --git a/meta/packages/linux/linux-moblin2-2.6.27-rc1/0003_i915.Add_support_for_MSI_and_interrupt_mitigation.patch b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0003_i915.Add_support_for_MSI_and_interrupt_mitigation.patch
new file mode 100644
index 0000000000..70f91194e4
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0003_i915.Add_support_for_MSI_and_interrupt_mitigation.patch
@@ -0,0 +1,421 @@
1From: Eric Anholt <eric@anholt.net>
2Date: Tue, 29 Jul 2008 19:10:39 +0000 (-0700)
3Subject: i915: Add support for MSI and interrupt mitigation.
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=aae4223e2fd3b29ae8e070b7a16d8cfc70c6a0c0
6
7i915: Add support for MSI and interrupt mitigation.
8
9Previous attempts at interrupt mitigation had been foiled by i915_wait_irq's
10failure to update the sarea seqno value when the status page indicated that
11the seqno had already been passed. MSI support has been seen to cut CPU
12costs by up to 40% in some workloads by avoiding other expensive interrupt
13handlers for frequent graphics interrupts.
14
15Signed-off-by: Eric Anholt <eric@anholt.net>
16---
17
18--- a/drivers/gpu/drm/drm_irq.c
19+++ b/drivers/gpu/drm/drm_irq.c
20@@ -63,7 +63,7 @@ int drm_irq_by_busid(struct drm_device *
21 p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
22 return -EINVAL;
23
24- p->irq = dev->irq;
25+ p->irq = dev->pdev->irq;
26
27 DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
28 p->irq);
29@@ -89,7 +89,7 @@ static int drm_irq_install(struct drm_de
30 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
31 return -EINVAL;
32
33- if (dev->irq == 0)
34+ if (dev->pdev->irq == 0)
35 return -EINVAL;
36
37 mutex_lock(&dev->struct_mutex);
38@@ -107,7 +107,7 @@ static int drm_irq_install(struct drm_de
39 dev->irq_enabled = 1;
40 mutex_unlock(&dev->struct_mutex);
41
42- DRM_DEBUG("irq=%d\n", dev->irq);
43+ DRM_DEBUG("irq=%d\n", dev->pdev->irq);
44
45 if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
46 init_waitqueue_head(&dev->vbl_queue);
47@@ -127,8 +127,12 @@ static int drm_irq_install(struct drm_de
48 if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
49 sh_flags = IRQF_SHARED;
50
51- ret = request_irq(dev->irq, dev->driver->irq_handler,
52+ ret = request_irq(dev->pdev->irq, dev->driver->irq_handler,
53 sh_flags, dev->devname, dev);
54+ /* Expose the device irq number to drivers that want to export it for
55+ * whatever reason.
56+ */
57+ dev->irq = dev->pdev->irq;
58 if (ret < 0) {
59 mutex_lock(&dev->struct_mutex);
60 dev->irq_enabled = 0;
61@@ -164,11 +168,11 @@ int drm_irq_uninstall(struct drm_device
62 if (!irq_enabled)
63 return -EINVAL;
64
65- DRM_DEBUG("irq=%d\n", dev->irq);
66+ DRM_DEBUG("irq=%d\n", dev->pdev->irq);
67
68 dev->driver->irq_uninstall(dev);
69
70- free_irq(dev->irq, dev);
71+ free_irq(dev->pdev->irq, dev);
72
73 dev->locked_tasklet_func = NULL;
74
75@@ -201,7 +205,7 @@ int drm_control(struct drm_device *dev,
76 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
77 return 0;
78 if (dev->if_version < DRM_IF_VERSION(1, 2) &&
79- ctl->irq != dev->irq)
80+ ctl->irq != dev->pdev->irq)
81 return -EINVAL;
82 return drm_irq_install(dev);
83 case DRM_UNINST_HANDLER:
84@@ -239,7 +243,7 @@ int drm_wait_vblank(struct drm_device *d
85 int ret = 0;
86 unsigned int flags, seq;
87
88- if ((!dev->irq) || (!dev->irq_enabled))
89+ if ((!dev->pdev->irq) || (!dev->irq_enabled))
90 return -EINVAL;
91
92 if (vblwait->request.type &
93--- a/drivers/gpu/drm/i915/i915_dma.c
94+++ b/drivers/gpu/drm/i915/i915_dma.c
95@@ -84,7 +84,7 @@ static int i915_dma_cleanup(struct drm_d
96 * may not have been called from userspace and after dev_private
97 * is freed, it's too late.
98 */
99- if (dev->irq)
100+ if (dev->irq_enabled)
101 drm_irq_uninstall(dev);
102
103 if (dev_priv->ring.virtual_start) {
104@@ -644,7 +644,7 @@ static int i915_getparam(struct drm_devi
105
106 switch (param->param) {
107 case I915_PARAM_IRQ_ACTIVE:
108- value = dev->irq ? 1 : 0;
109+ value = dev->irq_enabled;
110 break;
111 case I915_PARAM_ALLOW_BATCHBUFFER:
112 value = dev_priv->allow_batchbuffer ? 1 : 0;
113@@ -763,6 +763,20 @@ int i915_driver_load(struct drm_device *
114 ret = drm_addmap(dev, base, size, _DRM_REGISTERS,
115 _DRM_KERNEL | _DRM_DRIVER,
116 &dev_priv->mmio_map);
117+
118+
119+ /* On the 945G/GM, the chipset reports the MSI capability on the
120+ * integrated graphics even though the support isn't actually there
121+ * according to the published specs. It doesn't appear to function
122+ * correctly in testing on 945G.
123+ * This may be a side effect of MSI having been made available for PEG
124+ * and the registers being closely associated.
125+ */
126+ if (!IS_I945G(dev) && !IS_I945GM(dev))
127+ pci_enable_msi(dev->pdev);
128+
129+ spin_lock_init(&dev_priv->user_irq_lock);
130+
131 return ret;
132 }
133
134@@ -770,6 +784,9 @@ int i915_driver_unload(struct drm_device
135 {
136 struct drm_i915_private *dev_priv = dev->dev_private;
137
138+ if (dev->pdev->msi_enabled)
139+ pci_disable_msi(dev->pdev);
140+
141 if (dev_priv->mmio_map)
142 drm_rmmap(dev, dev_priv->mmio_map);
143
144--- a/drivers/gpu/drm/i915/i915_drv.h
145+++ b/drivers/gpu/drm/i915/i915_drv.h
146@@ -105,6 +105,12 @@ typedef struct drm_i915_private {
147 wait_queue_head_t irq_queue;
148 atomic_t irq_received;
149 atomic_t irq_emitted;
150+ /** Protects user_irq_refcount and irq_mask_reg */
151+ spinlock_t user_irq_lock;
152+ /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
153+ int user_irq_refcount;
154+ /** Cached value of IMR to avoid reads in updating the bitfield */
155+ u32 irq_mask_reg;
156
157 int tex_lru_log_granularity;
158 int allow_batchbuffer;
159--- a/drivers/gpu/drm/i915/i915_irq.c
160+++ b/drivers/gpu/drm/i915/i915_irq.c
161@@ -33,6 +33,31 @@
162
163 #define MAX_NOPID ((u32)~0)
164
165+/** These are the interrupts used by the driver */
166+#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
167+ I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | \
168+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
169+
170+static inline void
171+i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
172+{
173+ if ((dev_priv->irq_mask_reg & mask) != 0) {
174+ dev_priv->irq_mask_reg &= ~mask;
175+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
176+ (void) I915_READ(IMR);
177+ }
178+}
179+
180+static inline void
181+i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
182+{
183+ if ((dev_priv->irq_mask_reg & mask) != mask) {
184+ dev_priv->irq_mask_reg |= mask;
185+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
186+ (void) I915_READ(IMR);
187+ }
188+}
189+
190 /**
191 * Emit blits for scheduled buffer swaps.
192 *
193@@ -229,46 +254,50 @@ irqreturn_t i915_driver_irq_handler(DRM_
194 {
195 struct drm_device *dev = (struct drm_device *) arg;
196 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
197- u16 temp;
198 u32 pipea_stats, pipeb_stats;
199+ u32 iir;
200
201 pipea_stats = I915_READ(PIPEASTAT);
202 pipeb_stats = I915_READ(PIPEBSTAT);
203
204- temp = I915_READ16(IIR);
205-
206- temp &= (I915_USER_INTERRUPT |
207- I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
208- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT);
209-
210- DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
211-
212- if (temp == 0)
213+ if (dev->pdev->msi_enabled)
214+ I915_WRITE(IMR, ~0);
215+ iir = I915_READ(IIR);
216+
217+ DRM_DEBUG("iir=%08x\n", iir);
218+
219+ if (iir == 0) {
220+ if (dev->pdev->msi_enabled) {
221+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
222+ (void) I915_READ(IMR);
223+ }
224 return IRQ_NONE;
225+ }
226
227- I915_WRITE16(IIR, temp);
228- (void) I915_READ16(IIR);
229- DRM_READMEMORYBARRIER();
230+ I915_WRITE(IIR, iir);
231+ if (dev->pdev->msi_enabled)
232+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
233+ (void) I915_READ(IIR); /* Flush posted writes */
234
235 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
236
237- if (temp & I915_USER_INTERRUPT)
238+ if (iir & I915_USER_INTERRUPT)
239 DRM_WAKEUP(&dev_priv->irq_queue);
240
241- if (temp & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
242- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
243+ if (iir & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
244+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
245 int vblank_pipe = dev_priv->vblank_pipe;
246
247 if ((vblank_pipe &
248 (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
249 == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
250- if (temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
251+ if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
252 atomic_inc(&dev->vbl_received);
253- if (temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
254+ if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
255 atomic_inc(&dev->vbl_received2);
256- } else if (((temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
257+ } else if (((iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
258 (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
259- ((temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
260+ ((iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
261 (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
262 atomic_inc(&dev->vbl_received);
263
264@@ -314,6 +343,27 @@ static int i915_emit_irq(struct drm_devi
265 return dev_priv->counter;
266 }
267
268+static void i915_user_irq_get(struct drm_device *dev)
269+{
270+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
271+
272+ spin_lock(&dev_priv->user_irq_lock);
273+ if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1))
274+ i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
275+ spin_unlock(&dev_priv->user_irq_lock);
276+}
277+
278+static void i915_user_irq_put(struct drm_device *dev)
279+{
280+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
281+
282+ spin_lock(&dev_priv->user_irq_lock);
283+ BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
284+ if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0))
285+ i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
286+ spin_unlock(&dev_priv->user_irq_lock);
287+}
288+
289 static int i915_wait_irq(struct drm_device * dev, int irq_nr)
290 {
291 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
292@@ -322,13 +372,17 @@ static int i915_wait_irq(struct drm_devi
293 DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
294 READ_BREADCRUMB(dev_priv));
295
296- if (READ_BREADCRUMB(dev_priv) >= irq_nr)
297+ if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
298+ dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
299 return 0;
300+ }
301
302 dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
303
304+ i915_user_irq_get(dev);
305 DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
306 READ_BREADCRUMB(dev_priv) >= irq_nr);
307+ i915_user_irq_put(dev);
308
309 if (ret == -EBUSY) {
310 DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
311@@ -413,20 +467,6 @@ int i915_irq_wait(struct drm_device *dev
312 return i915_wait_irq(dev, irqwait->irq_seq);
313 }
314
315-static void i915_enable_interrupt (struct drm_device *dev)
316-{
317- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
318- u16 flag;
319-
320- flag = 0;
321- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
322- flag |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
323- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
324- flag |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
325-
326- I915_WRITE16(IER, I915_USER_INTERRUPT | flag);
327-}
328-
329 /* Set the vblank monitor pipe
330 */
331 int i915_vblank_pipe_set(struct drm_device *dev, void *data,
332@@ -434,6 +474,7 @@ int i915_vblank_pipe_set(struct drm_devi
333 {
334 drm_i915_private_t *dev_priv = dev->dev_private;
335 drm_i915_vblank_pipe_t *pipe = data;
336+ u32 enable_mask = 0, disable_mask = 0;
337
338 if (!dev_priv) {
339 DRM_ERROR("called with no initialization\n");
340@@ -445,9 +486,20 @@ int i915_vblank_pipe_set(struct drm_devi
341 return -EINVAL;
342 }
343
344- dev_priv->vblank_pipe = pipe->pipe;
345+ if (pipe->pipe & DRM_I915_VBLANK_PIPE_A)
346+ enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
347+ else
348+ disable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
349+
350+ if (pipe->pipe & DRM_I915_VBLANK_PIPE_B)
351+ enable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
352+ else
353+ disable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
354
355- i915_enable_interrupt (dev);
356+ i915_enable_irq(dev_priv, enable_mask);
357+ i915_disable_irq(dev_priv, disable_mask);
358+
359+ dev_priv->vblank_pipe = pipe->pipe;
360
361 return 0;
362 }
363@@ -464,7 +516,7 @@ int i915_vblank_pipe_get(struct drm_devi
364 return -EINVAL;
365 }
366
367- flag = I915_READ(IER);
368+ flag = I915_READ(IMR);
369 pipe->pipe = 0;
370 if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
371 pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
372@@ -586,9 +638,9 @@ void i915_driver_irq_preinstall(struct d
373 {
374 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
375
376- I915_WRITE16(HWSTAM, 0xfffe);
377- I915_WRITE16(IMR, 0x0);
378- I915_WRITE16(IER, 0x0);
379+ I915_WRITE(HWSTAM, 0xfffe);
380+ I915_WRITE(IMR, 0x0);
381+ I915_WRITE(IER, 0x0);
382 }
383
384 void i915_driver_irq_postinstall(struct drm_device * dev)
385@@ -601,7 +653,18 @@ void i915_driver_irq_postinstall(struct
386
387 if (!dev_priv->vblank_pipe)
388 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
389- i915_enable_interrupt(dev);
390+
391+ /* Set initial unmasked IRQs to just the selected vblank pipes. */
392+ dev_priv->irq_mask_reg = ~0;
393+ if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
394+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
395+ if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
396+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
397+
398+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
399+ I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
400+ (void) I915_READ(IER);
401+
402 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
403 }
404
405@@ -613,10 +676,10 @@ void i915_driver_irq_uninstall(struct dr
406 if (!dev_priv)
407 return;
408
409- I915_WRITE16(HWSTAM, 0xffff);
410- I915_WRITE16(IMR, 0xffff);
411- I915_WRITE16(IER, 0x0);
412+ I915_WRITE(HWSTAM, 0xffff);
413+ I915_WRITE(IMR, 0xffff);
414+ I915_WRITE(IER, 0x0);
415
416- temp = I915_READ16(IIR);
417- I915_WRITE16(IIR, temp);
418+ temp = I915_READ(IIR);
419+ I915_WRITE(IIR, temp);
420 }
421
diff --git a/meta/packages/linux/linux-moblin2-2.6.27-rc1/0004_i915.Track_progress_inside_of_batchbuffers_for_determining_wedgedness.patch b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0004_i915.Track_progress_inside_of_batchbuffers_for_determining_wedgedness.patch
new file mode 100644
index 0000000000..c391d16b76
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0004_i915.Track_progress_inside_of_batchbuffers_for_determining_wedgedness.patch
@@ -0,0 +1,47 @@
1From: Keith Packard <keithp@keithp.com>
2Date: Wed, 30 Jul 2008 19:21:20 +0000 (-0700)
3Subject: i915: Track progress inside of batchbuffers for determining wedgedness.
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=f0740db2246e4217384e8de32de6ebb4fbd807c9
6
7i915: Track progress inside of batchbuffers for determining wedgedness.
8
9This avoids early termination for long-running commands.
10
11Signed-off-by: Eric Anholt <eric@anholt.net>
12---
13
14--- a/drivers/gpu/drm/i915/i915_dma.c
15+++ b/drivers/gpu/drm/i915/i915_dma.c
16@@ -40,11 +40,15 @@ int i915_wait_ring(struct drm_device * d
17 {
18 drm_i915_private_t *dev_priv = dev->dev_private;
19 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
20+ u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
21+ u32 last_acthd = I915_READ(acthd_reg);
22+ u32 acthd;
23 u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
24 int i;
25
26- for (i = 0; i < 10000; i++) {
27+ for (i = 0; i < 100000; i++) {
28 ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
29+ acthd = I915_READ(acthd_reg);
30 ring->space = ring->head - (ring->tail + 8);
31 if (ring->space < 0)
32 ring->space += ring->Size;
33@@ -55,8 +59,13 @@ int i915_wait_ring(struct drm_device * d
34
35 if (ring->head != last_head)
36 i = 0;
37+ if (acthd != last_acthd)
38+ i = 0;
39
40 last_head = ring->head;
41+ last_acthd = acthd;
42+ msleep_interruptible(10);
43+
44 }
45
46 return -EBUSY;
47
diff --git a/meta/packages/linux/linux-moblin2-2.6.27-rc1/0005_i915.remove_settable_use_mi_batchbuffer_start.patch b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0005_i915.remove_settable_use_mi_batchbuffer_start.patch
new file mode 100644
index 0000000000..12362fef5a
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0005_i915.remove_settable_use_mi_batchbuffer_start.patch
@@ -0,0 +1,59 @@
1From: Keith Packard <keithp@keithp.com>
2Date: Wed, 30 Jul 2008 19:28:47 +0000 (-0700)
3Subject: i915: remove settable use_mi_batchbuffer_start
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=6fcd9a69a91c53d733870df20e095eea2b73620c
6
7i915: remove settable use_mi_batchbuffer_start
8
9The driver can know what hardware requires MI_BATCH_BUFFER vs
10MI_BATCH_BUFFER_START; there's no reason to let user mode configure this.
11
12Signed-off-by: Eric Anholt <eric@anholt.net>
13---
14
15--- a/drivers/gpu/drm/i915/i915_dma.c
16+++ b/drivers/gpu/drm/i915/i915_dma.c
17@@ -159,13 +159,6 @@ static int i915_initialize(struct drm_de
18 dev_priv->current_page = 0;
19 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
20
21- /* We are using separate values as placeholders for mechanisms for
22- * private backbuffer/depthbuffer usage.
23- */
24- dev_priv->use_mi_batchbuffer_start = 0;
25- if (IS_I965G(dev)) /* 965 doesn't support older method */
26- dev_priv->use_mi_batchbuffer_start = 1;
27-
28 /* Allow hardware batchbuffers unless told otherwise.
29 */
30 dev_priv->allow_batchbuffer = 1;
31@@ -486,7 +479,7 @@ static int i915_dispatch_batchbuffer(str
32 return ret;
33 }
34
35- if (dev_priv->use_mi_batchbuffer_start) {
36+ if (!IS_I830(dev) && !IS_845G(dev)) {
37 BEGIN_LP_RING(2);
38 if (IS_I965G(dev)) {
39 OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
40@@ -697,8 +690,6 @@ static int i915_setparam(struct drm_devi
41
42 switch (param->param) {
43 case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
44- if (!IS_I965G(dev))
45- dev_priv->use_mi_batchbuffer_start = param->value;
46 break;
47 case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
48 dev_priv->tex_lru_log_granularity = param->value;
49--- a/drivers/gpu/drm/i915/i915_drv.h
50+++ b/drivers/gpu/drm/i915/i915_drv.h
51@@ -99,7 +99,6 @@ typedef struct drm_i915_private {
52 int front_offset;
53 int current_page;
54 int page_flipping;
55- int use_mi_batchbuffer_start;
56
57 wait_queue_head_t irq_queue;
58 atomic_t irq_received;
59
diff --git a/meta/packages/linux/linux-moblin2-2.6.27-rc1/0006_i915.Ignore_X_server_provided_mmio_address.patch b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0006_i915.Ignore_X_server_provided_mmio_address.patch
new file mode 100644
index 0000000000..397f683af7
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0006_i915.Ignore_X_server_provided_mmio_address.patch
@@ -0,0 +1,42 @@
1From: Keith Packard <keithp@keithp.com>
2Date: Wed, 30 Jul 2008 19:36:08 +0000 (-0700)
3Subject: i915: Ignore X server provided mmio address
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=5d34a0e06e6e70b01ee070094322695b9e3f0029
6
7i915: Ignore X server provided mmio address
8
9It is already correctly detected by the kernel for use in suspend/resume.
10
11Signed-off-by: Eric Anholt <eric@anholt.net>
12---
13
14--- a/drivers/gpu/drm/i915/i915_dma.c
15+++ b/drivers/gpu/drm/i915/i915_dma.c
16@@ -121,13 +121,6 @@ static int i915_initialize(struct drm_de
17 return -EINVAL;
18 }
19
20- dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
21- if (!dev_priv->mmio_map) {
22- i915_dma_cleanup(dev);
23- DRM_ERROR("can not find mmio map!\n");
24- return -EINVAL;
25- }
26-
27 dev_priv->sarea_priv = (drm_i915_sarea_t *)
28 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
29
30@@ -194,11 +187,6 @@ static int i915_dma_resume(struct drm_de
31 return -EINVAL;
32 }
33
34- if (!dev_priv->mmio_map) {
35- DRM_ERROR("can not find mmio map!\n");
36- return -EINVAL;
37- }
38-
39 if (dev_priv->ring.map.handle == NULL) {
40 DRM_ERROR("can not ioremap virtual address for"
41 " ring buffer\n");
42
diff --git a/meta/packages/linux/linux-moblin2-2.6.27-rc1/0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch
new file mode 100644
index 0000000000..cf646f01c7
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch
@@ -0,0 +1,138 @@
1From: Keith Packard <keithp@keithp.com>
2Date: Wed, 30 Jul 2008 20:03:43 +0000 (-0700)
3Subject: i915: Initialize hardware status page at device load when possible.
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=ddb354254f88965f5f057e67ef775fbb4b35fef8
6
7i915: Initialize hardware status page at device load when possible.
8
9Some chips were unstable with repeated setup/teardown of the hardware status
10page.
11
12Signed-off-by: Eric Anholt <eric@anholt.net>
13---
14
15--- a/drivers/gpu/drm/i915/i915_dma.c
16+++ b/drivers/gpu/drm/i915/i915_dma.c
17@@ -71,6 +71,52 @@ int i915_wait_ring(struct drm_device * d
18 return -EBUSY;
19 }
20
21+/**
22+ * Sets up the hardware status page for devices that need a physical address
23+ * in the register.
24+ */
25+int i915_init_phys_hws(struct drm_device *dev)
26+{
27+ drm_i915_private_t *dev_priv = dev->dev_private;
28+ /* Program Hardware Status Page */
29+ dev_priv->status_page_dmah =
30+ drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
31+
32+ if (!dev_priv->status_page_dmah) {
33+ DRM_ERROR("Can not allocate hardware status page\n");
34+ return -ENOMEM;
35+ }
36+ dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
37+ dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
38+
39+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
40+
41+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
42+ DRM_DEBUG("Enabled hardware status page\n");
43+ return 0;
44+}
45+
46+/**
47+ * Frees the hardware status page, whether it's a physical address or a virtual
48+ * address set up by the X Server.
49+ */
50+void i915_free_hws(struct drm_device *dev)
51+{
52+ drm_i915_private_t *dev_priv = dev->dev_private;
53+ if (dev_priv->status_page_dmah) {
54+ drm_pci_free(dev, dev_priv->status_page_dmah);
55+ dev_priv->status_page_dmah = NULL;
56+ }
57+
58+ if (dev_priv->status_gfx_addr) {
59+ dev_priv->status_gfx_addr = 0;
60+ drm_core_ioremapfree(&dev_priv->hws_map, dev);
61+ }
62+
63+ /* Need to rewrite hardware status page */
64+ I915_WRITE(HWS_PGA, 0x1ffff000);
65+}
66+
67 void i915_kernel_lost_context(struct drm_device * dev)
68 {
69 drm_i915_private_t *dev_priv = dev->dev_private;
70@@ -103,18 +149,9 @@ static int i915_dma_cleanup(struct drm_d
71 dev_priv->ring.map.size = 0;
72 }
73
74- if (dev_priv->status_page_dmah) {
75- drm_pci_free(dev, dev_priv->status_page_dmah);
76- dev_priv->status_page_dmah = NULL;
77- /* Need to rewrite hardware status page */
78- I915_WRITE(HWS_PGA, 0x1ffff000);
79- }
80-
81- if (dev_priv->status_gfx_addr) {
82- dev_priv->status_gfx_addr = 0;
83- drm_core_ioremapfree(&dev_priv->hws_map, dev);
84- I915_WRITE(HWS_PGA, 0x1ffff000);
85- }
86+ /* Clear the HWS virtual address at teardown */
87+ if (I915_NEED_GFX_HWS(dev))
88+ i915_free_hws(dev);
89
90 return 0;
91 }
92@@ -165,23 +202,6 @@ static int i915_initialize(struct drm_de
93 */
94 dev_priv->allow_batchbuffer = 1;
95
96- /* Program Hardware Status Page */
97- if (!I915_NEED_GFX_HWS(dev)) {
98- dev_priv->status_page_dmah =
99- drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
100-
101- if (!dev_priv->status_page_dmah) {
102- i915_dma_cleanup(dev);
103- DRM_ERROR("Can not allocate hardware status page\n");
104- return -ENOMEM;
105- }
106- dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
107- dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
108-
109- memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
110- I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
111- }
112- DRM_DEBUG("Enabled hardware status page\n");
113 return 0;
114 }
115
116@@ -773,6 +793,12 @@ int i915_driver_load(struct drm_device *
117 _DRM_KERNEL | _DRM_DRIVER,
118 &dev_priv->mmio_map);
119
120+ /* Init HWS */
121+ if (!I915_NEED_GFX_HWS(dev)) {
122+ ret = i915_init_phys_hws(dev);
123+ if (ret != 0)
124+ return ret;
125+ }
126
127 /* On the 945G/GM, the chipset reports the MSI capability on the
128 * integrated graphics even though the support isn't actually there
129@@ -796,6 +822,8 @@ int i915_driver_unload(struct drm_device
130 if (dev->pdev->msi_enabled)
131 pci_disable_msi(dev->pdev);
132
133+ i915_free_hws(dev);
134+
135 if (dev_priv->mmio_map)
136 drm_rmmap(dev, dev_priv->mmio_map);
137
138
diff --git a/meta/packages/linux/linux-moblin2-2.6.27-rc1/0008_drm.Add_GEM_graphics_execution_manager_to_i915_driver.patch b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0008_drm.Add_GEM_graphics_execution_manager_to_i915_driver.patch
new file mode 100644
index 0000000000..e7ae851c4c
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0008_drm.Add_GEM_graphics_execution_manager_to_i915_driver.patch
@@ -0,0 +1,5453 @@
1From: Eric Anholt <eric@anholt.net>
2Date: Wed, 30 Jul 2008 19:06:12 +0000 (-0700)
3Subject: drm: Add GEM ("graphics execution manager") to i915 driver.
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=drm-gem-merge
6
7drm: Add GEM ("graphics execution manager") to i915 driver.
8
9GEM allows the creation of persistent buffer objects accessible by the
10graphics device through new ioctls for managing execution of commands on the
11device. The userland API is almost entirely driver-specific to ensure that
12any driver building on this model can easily map the interface to individual
13driver requirements.
14
15GEM is used by the 2d driver for managing its internal state allocations and
16will be used for pixmap storage to reduce memory consumption and enable
17zero-copy GLX_EXT_texture_from_pixmap, and in the 3d driver is used to enable
18GL_EXT_framebuffer_object and GL_ARB_pixel_buffer_object.
19
20Signed-off-by: Eric Anholt <eric@anholt.net>
21---
22
23--- a/drivers/gpu/drm/Makefile
24+++ b/drivers/gpu/drm/Makefile
25@@ -4,8 +4,9 @@
26
27 ccflags-y := -Iinclude/drm
28
29-drm-y := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
30- drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \
31+drm-y := drm_auth.o drm_bufs.o drm_cache.o \
32+ drm_context.o drm_dma.o drm_drawable.o \
33+ drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
34 drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
35 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
36 drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o
37--- a/drivers/gpu/drm/drm_agpsupport.c
38+++ b/drivers/gpu/drm/drm_agpsupport.c
39@@ -33,6 +33,7 @@
40
41 #include "drmP.h"
42 #include <linux/module.h>
43+#include <asm/agp.h>
44
45 #if __OS_HAS_AGP
46
47@@ -452,4 +453,52 @@ int drm_agp_unbind_memory(DRM_AGP_MEM *
48 return agp_unbind_memory(handle);
49 }
50
51-#endif /* __OS_HAS_AGP */
52+/**
53+ * Binds a collection of pages into AGP memory at the given offset, returning
54+ * the AGP memory structure containing them.
55+ *
56+ * No reference is held on the pages during this time -- it is up to the
57+ * caller to handle that.
58+ */
59+DRM_AGP_MEM *
60+drm_agp_bind_pages(struct drm_device *dev,
61+ struct page **pages,
62+ unsigned long num_pages,
63+ uint32_t gtt_offset)
64+{
65+ DRM_AGP_MEM *mem;
66+ int ret, i;
67+
68+ DRM_DEBUG("\n");
69+
70+ mem = drm_agp_allocate_memory(dev->agp->bridge, num_pages,
71+ AGP_USER_MEMORY);
72+ if (mem == NULL) {
73+ DRM_ERROR("Failed to allocate memory for %ld pages\n",
74+ num_pages);
75+ return NULL;
76+ }
77+
78+ for (i = 0; i < num_pages; i++)
79+ mem->memory[i] = phys_to_gart(page_to_phys(pages[i]));
80+ mem->page_count = num_pages;
81+
82+ mem->is_flushed = true;
83+ ret = drm_agp_bind_memory(mem, gtt_offset / PAGE_SIZE);
84+ if (ret != 0) {
85+ DRM_ERROR("Failed to bind AGP memory: %d\n", ret);
86+ agp_free_memory(mem);
87+ return NULL;
88+ }
89+
90+ return mem;
91+}
92+EXPORT_SYMBOL(drm_agp_bind_pages);
93+
94+void drm_agp_chipset_flush(struct drm_device *dev)
95+{
96+ agp_flush_chipset(dev->agp->bridge);
97+}
98+EXPORT_SYMBOL(drm_agp_chipset_flush);
99+
100+#endif /* __OS_HAS_AGP */
101--- /dev/null
102+++ b/drivers/gpu/drm/drm_cache.c
103@@ -0,0 +1,76 @@
104+/**************************************************************************
105+ *
106+ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
107+ * All Rights Reserved.
108+ *
109+ * Permission is hereby granted, free of charge, to any person obtaining a
110+ * copy of this software and associated documentation files (the
111+ * "Software"), to deal in the Software without restriction, including
112+ * without limitation the rights to use, copy, modify, merge, publish,
113+ * distribute, sub license, and/or sell copies of the Software, and to
114+ * permit persons to whom the Software is furnished to do so, subject to
115+ * the following conditions:
116+ *
117+ * The above copyright notice and this permission notice (including the
118+ * next paragraph) shall be included in all copies or substantial portions
119+ * of the Software.
120+ *
121+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
122+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
123+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
124+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
125+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
126+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
127+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
128+ *
129+ **************************************************************************/
130+/*
131+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
132+ */
133+
134+#include "drmP.h"
135+
136+#if defined(CONFIG_X86)
137+static void
138+drm_clflush_page(struct page *page)
139+{
140+ uint8_t *page_virtual;
141+ unsigned int i;
142+
143+ if (unlikely(page == NULL))
144+ return;
145+
146+ page_virtual = kmap_atomic(page, KM_USER0);
147+ for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
148+ clflush(page_virtual + i);
149+ kunmap_atomic(page_virtual, KM_USER0);
150+}
151+#endif
152+
153+static void
154+drm_clflush_ipi_handler(void *null)
155+{
156+ wbinvd();
157+}
158+
159+void
160+drm_clflush_pages(struct page *pages[], unsigned long num_pages)
161+{
162+
163+#if defined(CONFIG_X86)
164+ if (cpu_has_clflush) {
165+ unsigned long i;
166+
167+ mb();
168+ for (i = 0; i < num_pages; ++i)
169+ drm_clflush_page(*pages++);
170+ mb();
171+
172+ return;
173+ }
174+#endif
175+
176+ if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0)
177+ DRM_ERROR("Timed out waiting for cache flush.\n");
178+}
179+EXPORT_SYMBOL(drm_clflush_pages);
180--- a/drivers/gpu/drm/drm_drv.c
181+++ b/drivers/gpu/drm/drm_drv.c
182@@ -117,6 +117,10 @@ static struct drm_ioctl_desc drm_ioctls[
183 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
184
185 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
186+
187+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0),
188+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH),
189+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH),
190 };
191
192 #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
193--- a/drivers/gpu/drm/drm_fops.c
194+++ b/drivers/gpu/drm/drm_fops.c
195@@ -256,6 +256,9 @@ static int drm_open_helper(struct inode
196
197 INIT_LIST_HEAD(&priv->lhead);
198
199+ if (dev->driver->driver_features & DRIVER_GEM)
200+ drm_gem_open(dev, priv);
201+
202 if (dev->driver->open) {
203 ret = dev->driver->open(dev, priv);
204 if (ret < 0)
205@@ -400,6 +403,9 @@ int drm_release(struct inode *inode, str
206 dev->driver->reclaim_buffers(dev, file_priv);
207 }
208
209+ if (dev->driver->driver_features & DRIVER_GEM)
210+ drm_gem_release(dev, file_priv);
211+
212 drm_fasync(-1, filp, 0);
213
214 mutex_lock(&dev->ctxlist_mutex);
215--- /dev/null
216+++ b/drivers/gpu/drm/drm_gem.c
217@@ -0,0 +1,420 @@
218+/*
219+ * Copyright © 2008 Intel Corporation
220+ *
221+ * Permission is hereby granted, free of charge, to any person obtaining a
222+ * copy of this software and associated documentation files (the "Software"),
223+ * to deal in the Software without restriction, including without limitation
224+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
225+ * and/or sell copies of the Software, and to permit persons to whom the
226+ * Software is furnished to do so, subject to the following conditions:
227+ *
228+ * The above copyright notice and this permission notice (including the next
229+ * paragraph) shall be included in all copies or substantial portions of the
230+ * Software.
231+ *
232+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
233+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
234+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
235+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
236+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
237+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
238+ * IN THE SOFTWARE.
239+ *
240+ * Authors:
241+ * Eric Anholt <eric@anholt.net>
242+ *
243+ */
244+
245+#include <linux/types.h>
246+#include <linux/slab.h>
247+#include <linux/mm.h>
248+#include <linux/uaccess.h>
249+#include <linux/fs.h>
250+#include <linux/file.h>
251+#include <linux/module.h>
252+#include <linux/mman.h>
253+#include <linux/pagemap.h>
254+#include "drmP.h"
255+
256+/** @file drm_gem.c
257+ *
258+ * This file provides some of the base ioctls and library routines for
259+ * the graphics memory manager implemented by each device driver.
260+ *
261+ * Because various devices have different requirements in terms of
262+ * synchronization and migration strategies, implementing that is left up to
263+ * the driver, and all that the general API provides should be generic --
264+ * allocating objects, reading/writing data with the cpu, freeing objects.
265+ * Even there, platform-dependent optimizations for reading/writing data with
266+ * the CPU mean we'll likely hook those out to driver-specific calls. However,
267+ * the DRI2 implementation wants to have at least allocate/mmap be generic.
268+ *
269+ * The goal was to have swap-backed object allocation managed through
270+ * struct file. However, file descriptors as handles to a struct file have
271+ * two major failings:
272+ * - Process limits prevent more than 1024 or so being used at a time by
273+ * default.
274+ * - Inability to allocate high fds will aggravate the X Server's select()
275+ * handling, and likely that of many GL client applications as well.
276+ *
277+ * This led to a plan of using our own integer IDs (called handles, following
278+ * DRM terminology) to mimic fds, and implement the fd syscalls we need as
279+ * ioctls. The objects themselves will still include the struct file so
280+ * that we can transition to fds if the required kernel infrastructure shows
281+ * up at a later date, and as our interface with shmfs for memory allocation.
282+ */
283+
284+/**
285+ * Initialize the GEM device fields
286+ */
287+
288+int
289+drm_gem_init(struct drm_device *dev)
290+{
291+ spin_lock_init(&dev->object_name_lock);
292+ idr_init(&dev->object_name_idr);
293+ atomic_set(&dev->object_count, 0);
294+ atomic_set(&dev->object_memory, 0);
295+ atomic_set(&dev->pin_count, 0);
296+ atomic_set(&dev->pin_memory, 0);
297+ atomic_set(&dev->gtt_count, 0);
298+ atomic_set(&dev->gtt_memory, 0);
299+ return 0;
300+}
301+
302+/**
303+ * Allocate a GEM object of the specified size with shmfs backing store
304+ */
305+struct drm_gem_object *
306+drm_gem_object_alloc(struct drm_device *dev, size_t size)
307+{
308+ struct drm_gem_object *obj;
309+
310+ BUG_ON((size & (PAGE_SIZE - 1)) != 0);
311+
312+ obj = kcalloc(1, sizeof(*obj), GFP_KERNEL);
313+
314+ obj->dev = dev;
315+ obj->filp = shmem_file_setup("drm mm object", size, 0);
316+ if (IS_ERR(obj->filp)) {
317+ kfree(obj);
318+ return NULL;
319+ }
320+
321+ kref_init(&obj->refcount);
322+ kref_init(&obj->handlecount);
323+ obj->size = size;
324+ if (dev->driver->gem_init_object != NULL &&
325+ dev->driver->gem_init_object(obj) != 0) {
326+ fput(obj->filp);
327+ kfree(obj);
328+ return NULL;
329+ }
330+ atomic_inc(&dev->object_count);
331+ atomic_add(obj->size, &dev->object_memory);
332+ return obj;
333+}
334+EXPORT_SYMBOL(drm_gem_object_alloc);
335+
336+/**
337+ * Removes the mapping from handle to filp for this object.
338+ */
339+static int
340+drm_gem_handle_delete(struct drm_file *filp, int handle)
341+{
342+ struct drm_device *dev;
343+ struct drm_gem_object *obj;
344+
345+ /* This is gross. The idr system doesn't let us try a delete and
346+ * return an error code. It just spews if you fail at deleting.
347+ * So, we have to grab a lock around finding the object and then
348+ * doing the delete on it and dropping the refcount, or the user
349+ * could race us to double-decrement the refcount and cause a
350+ * use-after-free later. Given the frequency of our handle lookups,
351+ * we may want to use ida for number allocation and a hash table
352+ * for the pointers, anyway.
353+ */
354+ spin_lock(&filp->table_lock);
355+
356+ /* Check if we currently have a reference on the object */
357+ obj = idr_find(&filp->object_idr, handle);
358+ if (obj == NULL) {
359+ spin_unlock(&filp->table_lock);
360+ return -EINVAL;
361+ }
362+ dev = obj->dev;
363+
364+ /* Release reference and decrement refcount. */
365+ idr_remove(&filp->object_idr, handle);
366+ spin_unlock(&filp->table_lock);
367+
368+ mutex_lock(&dev->struct_mutex);
369+ drm_gem_object_handle_unreference(obj);
370+ mutex_unlock(&dev->struct_mutex);
371+
372+ return 0;
373+}
374+
375+/**
376+ * Create a handle for this object. This adds a handle reference
377+ * to the object, which includes a regular reference count. Callers
378+ * will likely want to dereference the object afterwards.
379+ */
380+int
381+drm_gem_handle_create(struct drm_file *file_priv,
382+ struct drm_gem_object *obj,
383+ int *handlep)
384+{
385+ int ret;
386+
387+ /*
388+ * Get the user-visible handle using idr.
389+ */
390+again:
391+ /* ensure there is space available to allocate a handle */
392+ if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0)
393+ return -ENOMEM;
394+
395+ /* do the allocation under our spinlock */
396+ spin_lock(&file_priv->table_lock);
397+ ret = idr_get_new_above(&file_priv->object_idr, obj, 1, handlep);
398+ spin_unlock(&file_priv->table_lock);
399+ if (ret == -EAGAIN)
400+ goto again;
401+
402+ if (ret != 0)
403+ return ret;
404+
405+ drm_gem_object_handle_reference(obj);
406+ return 0;
407+}
408+EXPORT_SYMBOL(drm_gem_handle_create);
409+
410+/** Returns a reference to the object named by the handle. */
411+struct drm_gem_object *
412+drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
413+ int handle)
414+{
415+ struct drm_gem_object *obj;
416+
417+ spin_lock(&filp->table_lock);
418+
419+ /* Check if we currently have a reference on the object */
420+ obj = idr_find(&filp->object_idr, handle);
421+ if (obj == NULL) {
422+ spin_unlock(&filp->table_lock);
423+ return NULL;
424+ }
425+
426+ drm_gem_object_reference(obj);
427+
428+ spin_unlock(&filp->table_lock);
429+
430+ return obj;
431+}
432+EXPORT_SYMBOL(drm_gem_object_lookup);
433+
434+/**
435+ * Releases the handle to an mm object.
436+ */
437+int
438+drm_gem_close_ioctl(struct drm_device *dev, void *data,
439+ struct drm_file *file_priv)
440+{
441+ struct drm_gem_close *args = data;
442+ int ret;
443+
444+ if (!(dev->driver->driver_features & DRIVER_GEM))
445+ return -ENODEV;
446+
447+ ret = drm_gem_handle_delete(file_priv, args->handle);
448+
449+ return ret;
450+}
451+
452+/**
453+ * Create a global name for an object, returning the name.
454+ *
455+ * Note that the name does not hold a reference; when the object
456+ * is freed, the name goes away.
457+ */
458+int
459+drm_gem_flink_ioctl(struct drm_device *dev, void *data,
460+ struct drm_file *file_priv)
461+{
462+ struct drm_gem_flink *args = data;
463+ struct drm_gem_object *obj;
464+ int ret;
465+
466+ if (!(dev->driver->driver_features & DRIVER_GEM))
467+ return -ENODEV;
468+
469+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
470+ if (obj == NULL)
471+ return -EINVAL;
472+
473+again:
474+ if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0)
475+ return -ENOMEM;
476+
477+ spin_lock(&dev->object_name_lock);
478+ if (obj->name) {
479+ spin_unlock(&dev->object_name_lock);
480+ return -EEXIST;
481+ }
482+ ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
483+ &obj->name);
484+ spin_unlock(&dev->object_name_lock);
485+ if (ret == -EAGAIN)
486+ goto again;
487+
488+ if (ret != 0) {
489+ mutex_lock(&dev->struct_mutex);
490+ drm_gem_object_unreference(obj);
491+ mutex_unlock(&dev->struct_mutex);
492+ return ret;
493+ }
494+
495+ /*
496+ * Leave the reference from the lookup around as the
497+ * name table now holds one
498+ */
499+ args->name = (uint64_t) obj->name;
500+
501+ return 0;
502+}
503+
504+/**
505+ * Open an object using the global name, returning a handle and the size.
506+ *
507+ * This handle (of course) holds a reference to the object, so the object
508+ * will not go away until the handle is deleted.
509+ */
510+int
511+drm_gem_open_ioctl(struct drm_device *dev, void *data,
512+ struct drm_file *file_priv)
513+{
514+ struct drm_gem_open *args = data;
515+ struct drm_gem_object *obj;
516+ int ret;
517+ int handle;
518+
519+ if (!(dev->driver->driver_features & DRIVER_GEM))
520+ return -ENODEV;
521+
522+ spin_lock(&dev->object_name_lock);
523+ obj = idr_find(&dev->object_name_idr, (int) args->name);
524+ if (obj)
525+ drm_gem_object_reference(obj);
526+ spin_unlock(&dev->object_name_lock);
527+ if (!obj)
528+ return -ENOENT;
529+
530+ ret = drm_gem_handle_create(file_priv, obj, &handle);
531+ mutex_lock(&dev->struct_mutex);
532+ drm_gem_object_unreference(obj);
533+ mutex_unlock(&dev->struct_mutex);
534+ if (ret)
535+ return ret;
536+
537+ args->handle = handle;
538+ args->size = obj->size;
539+
540+ return 0;
541+}
542+
543+/**
544+ * Called at device open time, sets up the structure for handling refcounting
545+ * of mm objects.
546+ */
547+void
548+drm_gem_open(struct drm_device *dev, struct drm_file *file_private)
549+{
550+ idr_init(&file_private->object_idr);
551+ spin_lock_init(&file_private->table_lock);
552+}
553+
554+/**
555+ * Called at device close to release the file's
556+ * handle references on objects.
557+ */
558+static int
559+drm_gem_object_release_handle(int id, void *ptr, void *data)
560+{
561+ struct drm_gem_object *obj = ptr;
562+
563+ drm_gem_object_handle_unreference(obj);
564+
565+ return 0;
566+}
567+
568+/**
569+ * Called at close time when the filp is going away.
570+ *
571+ * Releases any remaining references on objects by this filp.
572+ */
573+void
574+drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
575+{
576+ mutex_lock(&dev->struct_mutex);
577+ idr_for_each(&file_private->object_idr,
578+ &drm_gem_object_release_handle, NULL);
579+
580+ idr_destroy(&file_private->object_idr);
581+ mutex_unlock(&dev->struct_mutex);
582+}
583+
584+/**
585+ * Called after the last reference to the object has been lost.
586+ *
587+ * Frees the object
588+ */
589+void
590+drm_gem_object_free(struct kref *kref)
591+{
592+ struct drm_gem_object *obj = (struct drm_gem_object *) kref;
593+ struct drm_device *dev = obj->dev;
594+
595+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
596+
597+ if (dev->driver->gem_free_object != NULL)
598+ dev->driver->gem_free_object(obj);
599+
600+ fput(obj->filp);
601+ atomic_dec(&dev->object_count);
602+ atomic_sub(obj->size, &dev->object_memory);
603+ kfree(obj);
604+}
605+EXPORT_SYMBOL(drm_gem_object_free);
606+
607+/**
608+ * Called after the last handle to the object has been closed
609+ *
610+ * Removes any name for the object. Note that this must be
611+ * called before drm_gem_object_free or we'll be touching
612+ * freed memory
613+ */
614+void
615+drm_gem_object_handle_free(struct kref *kref)
616+{
617+ struct drm_gem_object *obj = container_of(kref,
618+ struct drm_gem_object,
619+ handlecount);
620+ struct drm_device *dev = obj->dev;
621+
622+ /* Remove any name for this object */
623+ spin_lock(&dev->object_name_lock);
624+ if (obj->name) {
625+ idr_remove(&dev->object_name_idr, obj->name);
626+ spin_unlock(&dev->object_name_lock);
627+ /*
628+ * The object name held a reference to this object, drop
629+ * that now.
630+ */
631+ drm_gem_object_unreference(obj);
632+ } else
633+ spin_unlock(&dev->object_name_lock);
634+
635+}
636+EXPORT_SYMBOL(drm_gem_object_handle_free);
637+
638--- a/drivers/gpu/drm/drm_memory.c
639+++ b/drivers/gpu/drm/drm_memory.c
640@@ -133,6 +133,7 @@ int drm_free_agp(DRM_AGP_MEM * handle, i
641 {
642 return drm_agp_free_memory(handle) ? 0 : -EINVAL;
643 }
644+EXPORT_SYMBOL(drm_free_agp);
645
646 /** Wrapper around agp_bind_memory() */
647 int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start)
648@@ -145,6 +146,7 @@ int drm_unbind_agp(DRM_AGP_MEM * handle)
649 {
650 return drm_agp_unbind_memory(handle);
651 }
652+EXPORT_SYMBOL(drm_unbind_agp);
653
654 #else /* __OS_HAS_AGP */
655 static inline void *agp_remap(unsigned long offset, unsigned long size,
656--- a/drivers/gpu/drm/drm_mm.c
657+++ b/drivers/gpu/drm/drm_mm.c
658@@ -169,6 +169,7 @@ struct drm_mm_node *drm_mm_get_block(str
659
660 return child;
661 }
662+EXPORT_SYMBOL(drm_mm_get_block);
663
664 /*
665 * Put a block. Merge with the previous and / or next block if they are free.
666@@ -217,6 +218,7 @@ void drm_mm_put_block(struct drm_mm_node
667 drm_free(cur, sizeof(*cur), DRM_MEM_MM);
668 }
669 }
670+EXPORT_SYMBOL(drm_mm_put_block);
671
672 struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm,
673 unsigned long size,
674@@ -265,6 +267,7 @@ int drm_mm_clean(struct drm_mm * mm)
675
676 return (head->next->next == head);
677 }
678+EXPORT_SYMBOL(drm_mm_search_free);
679
680 int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
681 {
682@@ -273,7 +276,7 @@ int drm_mm_init(struct drm_mm * mm, unsi
683
684 return drm_mm_create_tail_node(mm, start, size);
685 }
686-
687+EXPORT_SYMBOL(drm_mm_init);
688
689 void drm_mm_takedown(struct drm_mm * mm)
690 {
691--- a/drivers/gpu/drm/drm_proc.c
692+++ b/drivers/gpu/drm/drm_proc.c
693@@ -49,6 +49,10 @@ static int drm_queues_info(char *buf, ch
694 int request, int *eof, void *data);
695 static int drm_bufs_info(char *buf, char **start, off_t offset,
696 int request, int *eof, void *data);
697+static int drm_gem_name_info(char *buf, char **start, off_t offset,
698+ int request, int *eof, void *data);
699+static int drm_gem_object_info(char *buf, char **start, off_t offset,
700+ int request, int *eof, void *data);
701 #if DRM_DEBUG_CODE
702 static int drm_vma_info(char *buf, char **start, off_t offset,
703 int request, int *eof, void *data);
704@@ -60,13 +64,16 @@ static int drm_vma_info(char *buf, char
705 static struct drm_proc_list {
706 const char *name; /**< file name */
707 int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/
708+ u32 driver_features; /**< Required driver features for this entry */
709 } drm_proc_list[] = {
710- {"name", drm_name_info},
711- {"mem", drm_mem_info},
712- {"vm", drm_vm_info},
713- {"clients", drm_clients_info},
714- {"queues", drm_queues_info},
715- {"bufs", drm_bufs_info},
716+ {"name", drm_name_info, 0},
717+ {"mem", drm_mem_info, 0},
718+ {"vm", drm_vm_info, 0},
719+ {"clients", drm_clients_info, 0},
720+ {"queues", drm_queues_info, 0},
721+ {"bufs", drm_bufs_info, 0},
722+ {"gem_names", drm_gem_name_info, DRIVER_GEM},
723+ {"gem_objects", drm_gem_object_info, DRIVER_GEM},
724 #if DRM_DEBUG_CODE
725 {"vma", drm_vma_info},
726 #endif
727@@ -90,8 +97,9 @@ static struct drm_proc_list {
728 int drm_proc_init(struct drm_minor *minor, int minor_id,
729 struct proc_dir_entry *root)
730 {
731+ struct drm_device *dev = minor->dev;
732 struct proc_dir_entry *ent;
733- int i, j;
734+ int i, j, ret;
735 char name[64];
736
737 sprintf(name, "%d", minor_id);
738@@ -102,23 +110,42 @@ int drm_proc_init(struct drm_minor *mino
739 }
740
741 for (i = 0; i < DRM_PROC_ENTRIES; i++) {
742+ u32 features = drm_proc_list[i].driver_features;
743+
744+ if (features != 0 &&
745+ (dev->driver->driver_features & features) != features)
746+ continue;
747+
748 ent = create_proc_entry(drm_proc_list[i].name,
749 S_IFREG | S_IRUGO, minor->dev_root);
750 if (!ent) {
751 DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
752 name, drm_proc_list[i].name);
753- for (j = 0; j < i; j++)
754- remove_proc_entry(drm_proc_list[i].name,
755- minor->dev_root);
756- remove_proc_entry(name, root);
757- minor->dev_root = NULL;
758- return -1;
759+ ret = -1;
760+ goto fail;
761 }
762 ent->read_proc = drm_proc_list[i].f;
763 ent->data = minor;
764 }
765
766+ if (dev->driver->proc_init) {
767+ ret = dev->driver->proc_init(minor);
768+ if (ret) {
769+ DRM_ERROR("DRM: Driver failed to initialize "
770+ "/proc/dri.\n");
771+ goto fail;
772+ }
773+ }
774+
775 return 0;
776+ fail:
777+
778+ for (j = 0; j < i; j++)
779+ remove_proc_entry(drm_proc_list[i].name,
780+ minor->dev_root);
781+ remove_proc_entry(name, root);
782+ minor->dev_root = NULL;
783+ return ret;
784 }
785
786 /**
787@@ -133,12 +160,16 @@ int drm_proc_init(struct drm_minor *mino
788 */
789 int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
790 {
791+ struct drm_device *dev = minor->dev;
792 int i;
793 char name[64];
794
795 if (!root || !minor->dev_root)
796 return 0;
797
798+ if (dev->driver->proc_cleanup)
799+ dev->driver->proc_cleanup(minor);
800+
801 for (i = 0; i < DRM_PROC_ENTRIES; i++)
802 remove_proc_entry(drm_proc_list[i].name, minor->dev_root);
803 sprintf(name, "%d", minor->index);
804@@ -480,6 +511,84 @@ static int drm_clients_info(char *buf, c
805 return ret;
806 }
807
808+struct drm_gem_name_info_data {
809+ int len;
810+ char *buf;
811+ int eof;
812+};
813+
814+static int drm_gem_one_name_info(int id, void *ptr, void *data)
815+{
816+ struct drm_gem_object *obj = ptr;
817+ struct drm_gem_name_info_data *nid = data;
818+
819+ DRM_INFO("name %d size %d\n", obj->name, obj->size);
820+ if (nid->eof)
821+ return 0;
822+
823+ nid->len += sprintf(&nid->buf[nid->len],
824+ "%6d%9d%8d%9d\n",
825+ obj->name, obj->size,
826+ atomic_read(&obj->handlecount.refcount),
827+ atomic_read(&obj->refcount.refcount));
828+ if (nid->len > DRM_PROC_LIMIT) {
829+ nid->eof = 1;
830+ return 0;
831+ }
832+ return 0;
833+}
834+
835+static int drm_gem_name_info(char *buf, char **start, off_t offset,
836+ int request, int *eof, void *data)
837+{
838+ struct drm_minor *minor = (struct drm_minor *) data;
839+ struct drm_device *dev = minor->dev;
840+ struct drm_gem_name_info_data nid;
841+
842+ if (offset > DRM_PROC_LIMIT) {
843+ *eof = 1;
844+ return 0;
845+ }
846+
847+ nid.len = sprintf(buf, " name size handles refcount\n");
848+ nid.buf = buf;
849+ nid.eof = 0;
850+ idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, &nid);
851+
852+ *start = &buf[offset];
853+ *eof = 0;
854+ if (nid.len > request + offset)
855+ return request;
856+ *eof = 1;
857+ return nid.len - offset;
858+}
859+
860+static int drm_gem_object_info(char *buf, char **start, off_t offset,
861+ int request, int *eof, void *data)
862+{
863+ struct drm_minor *minor = (struct drm_minor *) data;
864+ struct drm_device *dev = minor->dev;
865+ int len = 0;
866+
867+ if (offset > DRM_PROC_LIMIT) {
868+ *eof = 1;
869+ return 0;
870+ }
871+
872+ *start = &buf[offset];
873+ *eof = 0;
874+ DRM_PROC_PRINT("%d objects\n", atomic_read(&dev->object_count));
875+ DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory));
876+ DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count));
877+ DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory));
878+ DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory));
879+ DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total);
880+ if (len > request + offset)
881+ return request;
882+ *eof = 1;
883+ return len - offset;
884+}
885+
886 #if DRM_DEBUG_CODE
887
888 static int drm__vma_info(char *buf, char **start, off_t offset, int request,
889--- a/drivers/gpu/drm/drm_stub.c
890+++ b/drivers/gpu/drm/drm_stub.c
891@@ -152,6 +152,15 @@ static int drm_fill_in_dev(struct drm_de
892 goto error_out_unreg;
893 }
894
895+ if (driver->driver_features & DRIVER_GEM) {
896+ retcode = drm_gem_init(dev);
897+ if (retcode) {
898+ DRM_ERROR("Cannot initialize graphics execution "
899+ "manager (GEM)\n");
900+ goto error_out_unreg;
901+ }
902+ }
903+
904 return 0;
905
906 error_out_unreg:
907@@ -317,6 +326,7 @@ int drm_put_dev(struct drm_device * dev)
908 int drm_put_minor(struct drm_minor **minor_p)
909 {
910 struct drm_minor *minor = *minor_p;
911+
912 DRM_DEBUG("release secondary minor %d\n", minor->index);
913
914 if (minor->type == DRM_MINOR_LEGACY)
915--- a/drivers/gpu/drm/i915/Makefile
916+++ b/drivers/gpu/drm/i915/Makefile
917@@ -3,7 +3,11 @@
918 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
919
920 ccflags-y := -Iinclude/drm
921-i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
922+i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
923+ i915_gem.o \
924+ i915_gem_debug.o \
925+ i915_gem_proc.o \
926+ i915_gem_tiling.o
927
928 i915-$(CONFIG_COMPAT) += i915_ioc32.o
929
930--- a/drivers/gpu/drm/i915/i915_dma.c
931+++ b/drivers/gpu/drm/i915/i915_dma.c
932@@ -170,24 +170,31 @@ static int i915_initialize(struct drm_de
933 dev_priv->sarea_priv = (drm_i915_sarea_t *)
934 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
935
936- dev_priv->ring.Start = init->ring_start;
937- dev_priv->ring.End = init->ring_end;
938- dev_priv->ring.Size = init->ring_size;
939- dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
940-
941- dev_priv->ring.map.offset = init->ring_start;
942- dev_priv->ring.map.size = init->ring_size;
943- dev_priv->ring.map.type = 0;
944- dev_priv->ring.map.flags = 0;
945- dev_priv->ring.map.mtrr = 0;
946+ if (init->ring_size != 0) {
947+ if (dev_priv->ring.ring_obj != NULL) {
948+ i915_dma_cleanup(dev);
949+ DRM_ERROR("Client tried to initialize ringbuffer in "
950+ "GEM mode\n");
951+ return -EINVAL;
952+ }
953
954- drm_core_ioremap(&dev_priv->ring.map, dev);
955+ dev_priv->ring.Size = init->ring_size;
956+ dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
957
958- if (dev_priv->ring.map.handle == NULL) {
959- i915_dma_cleanup(dev);
960- DRM_ERROR("can not ioremap virtual address for"
961- " ring buffer\n");
962- return -ENOMEM;
963+ dev_priv->ring.map.offset = init->ring_start;
964+ dev_priv->ring.map.size = init->ring_size;
965+ dev_priv->ring.map.type = 0;
966+ dev_priv->ring.map.flags = 0;
967+ dev_priv->ring.map.mtrr = 0;
968+
969+ drm_core_ioremap(&dev_priv->ring.map, dev);
970+
971+ if (dev_priv->ring.map.handle == NULL) {
972+ i915_dma_cleanup(dev);
973+ DRM_ERROR("can not ioremap virtual address for"
974+ " ring buffer\n");
975+ return -ENOMEM;
976+ }
977 }
978
979 dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
980@@ -377,9 +384,10 @@ static int i915_emit_cmds(struct drm_dev
981 return 0;
982 }
983
984-static int i915_emit_box(struct drm_device * dev,
985- struct drm_clip_rect __user * boxes,
986- int i, int DR1, int DR4)
987+int
988+i915_emit_box(struct drm_device *dev,
989+ struct drm_clip_rect __user *boxes,
990+ int i, int DR1, int DR4)
991 {
992 drm_i915_private_t *dev_priv = dev->dev_private;
993 struct drm_clip_rect box;
994@@ -681,6 +689,9 @@ static int i915_getparam(struct drm_devi
995 case I915_PARAM_LAST_DISPATCH:
996 value = READ_BREADCRUMB(dev_priv);
997 break;
998+ case I915_PARAM_HAS_GEM:
999+ value = 1;
1000+ break;
1001 default:
1002 DRM_ERROR("Unknown parameter %d\n", param->param);
1003 return -EINVAL;
1004@@ -784,6 +795,7 @@ int i915_driver_load(struct drm_device *
1005 memset(dev_priv, 0, sizeof(drm_i915_private_t));
1006
1007 dev->dev_private = (void *)dev_priv;
1008+ dev_priv->dev = dev;
1009
1010 /* Add register map (needed for suspend/resume) */
1011 base = drm_get_resource_start(dev, mmio_bar);
1012@@ -793,6 +805,8 @@ int i915_driver_load(struct drm_device *
1013 _DRM_KERNEL | _DRM_DRIVER,
1014 &dev_priv->mmio_map);
1015
1016+ i915_gem_load(dev);
1017+
1018 /* Init HWS */
1019 if (!I915_NEED_GFX_HWS(dev)) {
1020 ret = i915_init_phys_hws(dev);
1021@@ -833,6 +847,25 @@ int i915_driver_unload(struct drm_device
1022 return 0;
1023 }
1024
1025+int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
1026+{
1027+ struct drm_i915_file_private *i915_file_priv;
1028+
1029+ DRM_DEBUG("\n");
1030+ i915_file_priv = (struct drm_i915_file_private *)
1031+ drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES);
1032+
1033+ if (!i915_file_priv)
1034+ return -ENOMEM;
1035+
1036+ file_priv->driver_priv = i915_file_priv;
1037+
1038+ i915_file_priv->mm.last_gem_seqno = 0;
1039+ i915_file_priv->mm.last_gem_throttle_seqno = 0;
1040+
1041+ return 0;
1042+}
1043+
1044 void i915_driver_lastclose(struct drm_device * dev)
1045 {
1046 drm_i915_private_t *dev_priv = dev->dev_private;
1047@@ -840,6 +873,8 @@ void i915_driver_lastclose(struct drm_de
1048 if (!dev_priv)
1049 return;
1050
1051+ i915_gem_lastclose(dev);
1052+
1053 if (dev_priv->agp_heap)
1054 i915_mem_takedown(&(dev_priv->agp_heap));
1055
1056@@ -852,6 +887,13 @@ void i915_driver_preclose(struct drm_dev
1057 i915_mem_release(dev, file_priv, dev_priv->agp_heap);
1058 }
1059
1060+void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
1061+{
1062+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
1063+
1064+ drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES);
1065+}
1066+
1067 struct drm_ioctl_desc i915_ioctls[] = {
1068 DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1069 DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
1070@@ -870,6 +912,22 @@ struct drm_ioctl_desc i915_ioctls[] = {
1071 DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ),
1072 DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
1073 DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH),
1074+ DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH),
1075+ DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
1076+ DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
1077+ DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
1078+ DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH),
1079+ DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH),
1080+ DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH),
1081+ DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH),
1082+ DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0),
1083+ DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0),
1084+ DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
1085+ DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
1086+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
1087+ DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0),
1088+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
1089+ DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
1090 };
1091
1092 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
1093--- a/drivers/gpu/drm/i915/i915_drv.c
1094+++ b/drivers/gpu/drm/i915/i915_drv.c
1095@@ -542,11 +542,13 @@ static struct drm_driver driver = {
1096 .driver_features =
1097 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
1098 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL |
1099- DRIVER_IRQ_VBL2,
1100+ DRIVER_IRQ_VBL2 | DRIVER_GEM,
1101 .load = i915_driver_load,
1102 .unload = i915_driver_unload,
1103+ .open = i915_driver_open,
1104 .lastclose = i915_driver_lastclose,
1105 .preclose = i915_driver_preclose,
1106+ .postclose = i915_driver_postclose,
1107 .suspend = i915_suspend,
1108 .resume = i915_resume,
1109 .device_is_agp = i915_driver_device_is_agp,
1110@@ -559,6 +561,10 @@ static struct drm_driver driver = {
1111 .reclaim_buffers = drm_core_reclaim_buffers,
1112 .get_map_ofs = drm_core_get_map_ofs,
1113 .get_reg_ofs = drm_core_get_reg_ofs,
1114+ .proc_init = i915_gem_proc_init,
1115+ .proc_cleanup = i915_gem_proc_cleanup,
1116+ .gem_init_object = i915_gem_init_object,
1117+ .gem_free_object = i915_gem_free_object,
1118 .ioctls = i915_ioctls,
1119 .fops = {
1120 .owner = THIS_MODULE,
1121--- a/drivers/gpu/drm/i915/i915_drv.h
1122+++ b/drivers/gpu/drm/i915/i915_drv.h
1123@@ -39,7 +39,7 @@
1124
1125 #define DRIVER_NAME "i915"
1126 #define DRIVER_DESC "Intel Graphics"
1127-#define DRIVER_DATE "20060119"
1128+#define DRIVER_DATE "20080730"
1129
1130 /* Interface history:
1131 *
1132@@ -55,16 +55,23 @@
1133 #define DRIVER_MINOR 6
1134 #define DRIVER_PATCHLEVEL 0
1135
1136+#define WATCH_COHERENCY 0
1137+#define WATCH_BUF 0
1138+#define WATCH_EXEC 0
1139+#define WATCH_LRU 0
1140+#define WATCH_RELOC 0
1141+#define WATCH_INACTIVE 0
1142+#define WATCH_PWRITE 0
1143+
1144 typedef struct _drm_i915_ring_buffer {
1145 int tail_mask;
1146- unsigned long Start;
1147- unsigned long End;
1148 unsigned long Size;
1149 u8 *virtual_start;
1150 int head;
1151 int tail;
1152 int space;
1153 drm_local_map_t map;
1154+ struct drm_gem_object *ring_obj;
1155 } drm_i915_ring_buffer_t;
1156
1157 struct mem_block {
1158@@ -83,6 +90,8 @@ typedef struct _drm_i915_vbl_swap {
1159 } drm_i915_vbl_swap_t;
1160
1161 typedef struct drm_i915_private {
1162+ struct drm_device *dev;
1163+
1164 drm_local_map_t *sarea;
1165 drm_local_map_t *mmio_map;
1166
1167@@ -95,6 +104,7 @@ typedef struct drm_i915_private {
1168 unsigned long counter;
1169 unsigned int status_gfx_addr;
1170 drm_local_map_t hws_map;
1171+ struct drm_gem_object *hws_obj;
1172
1173 unsigned int cpp;
1174 int back_offset;
1175@@ -104,7 +114,6 @@ typedef struct drm_i915_private {
1176
1177 wait_queue_head_t irq_queue;
1178 atomic_t irq_received;
1179- atomic_t irq_emitted;
1180 /** Protects user_irq_refcount and irq_mask_reg */
1181 spinlock_t user_irq_lock;
1182 /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
1183@@ -210,8 +219,174 @@ typedef struct drm_i915_private {
1184 u8 saveDACMASK;
1185 u8 saveDACDATA[256*3]; /* 256 3-byte colors */
1186 u8 saveCR[37];
1187+
1188+ struct {
1189+ struct drm_mm gtt_space;
1190+
1191+ /**
1192+ * List of objects currently involved in rendering from the
1193+ * ringbuffer.
1194+ *
1195+ * A reference is held on the buffer while on this list.
1196+ */
1197+ struct list_head active_list;
1198+
1199+ /**
1200+ * List of objects which are not in the ringbuffer but which
1201+ * still have a write_domain which needs to be flushed before
1202+ * unbinding.
1203+ *
1204+ * A reference is held on the buffer while on this list.
1205+ */
1206+ struct list_head flushing_list;
1207+
1208+ /**
1209+ * LRU list of objects which are not in the ringbuffer and
1210+ * are ready to unbind, but are still in the GTT.
1211+ *
1212+ * A reference is not held on the buffer while on this list,
1213+ * as merely being GTT-bound shouldn't prevent its being
1214+ * freed, and we'll pull it off the list in the free path.
1215+ */
1216+ struct list_head inactive_list;
1217+
1218+ /**
1219+ * List of breadcrumbs associated with GPU requests currently
1220+ * outstanding.
1221+ */
1222+ struct list_head request_list;
1223+
1224+ /**
1225+ * We leave the user IRQ off as much as possible,
1226+ * but this means that requests will finish and never
1227+ * be retired once the system goes idle. Set a timer to
1228+ * fire periodically while the ring is running. When it
1229+ * fires, go retire requests.
1230+ */
1231+ struct delayed_work retire_work;
1232+
1233+ uint32_t next_gem_seqno;
1234+
1235+ /**
1236+ * Waiting sequence number, if any
1237+ */
1238+ uint32_t waiting_gem_seqno;
1239+
1240+ /**
1241+ * Last seq seen at irq time
1242+ */
1243+ uint32_t irq_gem_seqno;
1244+
1245+ /**
1246+ * Flag if the X Server, and thus DRM, is not currently in
1247+ * control of the device.
1248+ *
1249+ * This is set between LeaveVT and EnterVT. It needs to be
1250+ * replaced with a semaphore. It also needs to be
1251+ * transitioned away from for kernel modesetting.
1252+ */
1253+ int suspended;
1254+
1255+ /**
1256+ * Flag if the hardware appears to be wedged.
1257+ *
1258+ * This is set when attempts to idle the device timeout.
1259+ * It prevents command submission from occuring and makes
1260+ * every pending request fail
1261+ */
1262+ int wedged;
1263+
1264+ /** Bit 6 swizzling required for X tiling */
1265+ uint32_t bit_6_swizzle_x;
1266+ /** Bit 6 swizzling required for Y tiling */
1267+ uint32_t bit_6_swizzle_y;
1268+ } mm;
1269 } drm_i915_private_t;
1270
1271+/** driver private structure attached to each drm_gem_object */
1272+struct drm_i915_gem_object {
1273+ struct drm_gem_object *obj;
1274+
1275+ /** Current space allocated to this object in the GTT, if any. */
1276+ struct drm_mm_node *gtt_space;
1277+
1278+ /** This object's place on the active/flushing/inactive lists */
1279+ struct list_head list;
1280+
1281+ /**
1282+ * This is set if the object is on the active or flushing lists
1283+ * (has pending rendering), and is not set if it's on inactive (ready
1284+ * to be unbound).
1285+ */
1286+ int active;
1287+
1288+ /**
1289+ * This is set if the object has been written to since last bound
1290+ * to the GTT
1291+ */
1292+ int dirty;
1293+
1294+ /** AGP memory structure for our GTT binding. */
1295+ DRM_AGP_MEM *agp_mem;
1296+
1297+ struct page **page_list;
1298+
1299+ /**
1300+ * Current offset of the object in GTT space.
1301+ *
1302+ * This is the same as gtt_space->start
1303+ */
1304+ uint32_t gtt_offset;
1305+
1306+ /** Boolean whether this object has a valid gtt offset. */
1307+ int gtt_bound;
1308+
1309+ /** How many users have pinned this object in GTT space */
1310+ int pin_count;
1311+
1312+ /** Breadcrumb of last rendering to the buffer. */
1313+ uint32_t last_rendering_seqno;
1314+
1315+ /** Current tiling mode for the object. */
1316+ uint32_t tiling_mode;
1317+
1318+ /**
1319+ * Flagging of which individual pages are valid in GEM_DOMAIN_CPU when
1320+ * GEM_DOMAIN_CPU is not in the object's read domain.
1321+ */
1322+ uint8_t *page_cpu_valid;
1323+};
1324+
1325+/**
1326+ * Request queue structure.
1327+ *
1328+ * The request queue allows us to note sequence numbers that have been emitted
1329+ * and may be associated with active buffers to be retired.
1330+ *
1331+ * By keeping this list, we can avoid having to do questionable
1332+ * sequence-number comparisons on buffer last_rendering_seqnos, and associate
1333+ * an emission time with seqnos for tracking how far ahead of the GPU we are.
1334+ */
1335+struct drm_i915_gem_request {
1336+ /** GEM sequence number associated with this request. */
1337+ uint32_t seqno;
1338+
1339+ /** Time at which this request was emitted, in jiffies. */
1340+ unsigned long emitted_jiffies;
1341+
1342+ /** Cache domains that were flushed at the start of the request. */
1343+ uint32_t flush_domains;
1344+
1345+ struct list_head list;
1346+};
1347+
1348+struct drm_i915_file_private {
1349+ struct {
1350+ uint32_t last_gem_seqno;
1351+ uint32_t last_gem_throttle_seqno;
1352+ } mm;
1353+};
1354+
1355 extern struct drm_ioctl_desc i915_ioctls[];
1356 extern int i915_max_ioctl;
1357
1358@@ -219,18 +394,26 @@ extern int i915_max_ioctl;
1359 extern void i915_kernel_lost_context(struct drm_device * dev);
1360 extern int i915_driver_load(struct drm_device *, unsigned long flags);
1361 extern int i915_driver_unload(struct drm_device *);
1362+extern int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv);
1363 extern void i915_driver_lastclose(struct drm_device * dev);
1364 extern void i915_driver_preclose(struct drm_device *dev,
1365 struct drm_file *file_priv);
1366+extern void i915_driver_postclose(struct drm_device *dev,
1367+ struct drm_file *file_priv);
1368 extern int i915_driver_device_is_agp(struct drm_device * dev);
1369 extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
1370 unsigned long arg);
1371+extern int i915_emit_box(struct drm_device *dev,
1372+ struct drm_clip_rect __user *boxes,
1373+ int i, int DR1, int DR4);
1374
1375 /* i915_irq.c */
1376 extern int i915_irq_emit(struct drm_device *dev, void *data,
1377 struct drm_file *file_priv);
1378 extern int i915_irq_wait(struct drm_device *dev, void *data,
1379 struct drm_file *file_priv);
1380+void i915_user_irq_get(struct drm_device *dev);
1381+void i915_user_irq_put(struct drm_device *dev);
1382
1383 extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
1384 extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
1385@@ -257,6 +440,67 @@ extern int i915_mem_destroy_heap(struct
1386 extern void i915_mem_takedown(struct mem_block **heap);
1387 extern void i915_mem_release(struct drm_device * dev,
1388 struct drm_file *file_priv, struct mem_block *heap);
1389+/* i915_gem.c */
1390+int i915_gem_init_ioctl(struct drm_device *dev, void *data,
1391+ struct drm_file *file_priv);
1392+int i915_gem_create_ioctl(struct drm_device *dev, void *data,
1393+ struct drm_file *file_priv);
1394+int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
1395+ struct drm_file *file_priv);
1396+int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
1397+ struct drm_file *file_priv);
1398+int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
1399+ struct drm_file *file_priv);
1400+int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1401+ struct drm_file *file_priv);
1402+int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
1403+ struct drm_file *file_priv);
1404+int i915_gem_execbuffer(struct drm_device *dev, void *data,
1405+ struct drm_file *file_priv);
1406+int i915_gem_pin_ioctl(struct drm_device *dev, void *data,
1407+ struct drm_file *file_priv);
1408+int i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
1409+ struct drm_file *file_priv);
1410+int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
1411+ struct drm_file *file_priv);
1412+int i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
1413+ struct drm_file *file_priv);
1414+int i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
1415+ struct drm_file *file_priv);
1416+int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
1417+ struct drm_file *file_priv);
1418+int i915_gem_set_tiling(struct drm_device *dev, void *data,
1419+ struct drm_file *file_priv);
1420+int i915_gem_get_tiling(struct drm_device *dev, void *data,
1421+ struct drm_file *file_priv);
1422+void i915_gem_load(struct drm_device *dev);
1423+int i915_gem_proc_init(struct drm_minor *minor);
1424+void i915_gem_proc_cleanup(struct drm_minor *minor);
1425+int i915_gem_init_object(struct drm_gem_object *obj);
1426+void i915_gem_free_object(struct drm_gem_object *obj);
1427+int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
1428+void i915_gem_object_unpin(struct drm_gem_object *obj);
1429+void i915_gem_lastclose(struct drm_device *dev);
1430+uint32_t i915_get_gem_seqno(struct drm_device *dev);
1431+void i915_gem_retire_requests(struct drm_device *dev);
1432+void i915_gem_retire_work_handler(struct work_struct *work);
1433+void i915_gem_clflush_object(struct drm_gem_object *obj);
1434+
1435+/* i915_gem_tiling.c */
1436+void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
1437+
1438+/* i915_gem_debug.c */
1439+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
1440+ const char *where, uint32_t mark);
1441+#if WATCH_INACTIVE
1442+void i915_verify_inactive(struct drm_device *dev, char *file, int line);
1443+#else
1444+#define i915_verify_inactive(dev, file, line)
1445+#endif
1446+void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle);
1447+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
1448+ const char *where, uint32_t mark);
1449+void i915_dump_lru(struct drm_device *dev, const char *where);
1450
1451 #define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
1452 #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
1453@@ -309,6 +553,7 @@ extern void i915_mem_release(struct drm_
1454 */
1455 #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
1456 #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5)
1457+#define I915_GEM_HWS_INDEX 0x10
1458
1459 extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1460
1461--- /dev/null
1462+++ b/drivers/gpu/drm/i915/i915_gem.c
1463@@ -0,0 +1,2508 @@
1464+/*
1465+ * Copyright © 2008 Intel Corporation
1466+ *
1467+ * Permission is hereby granted, free of charge, to any person obtaining a
1468+ * copy of this software and associated documentation files (the "Software"),
1469+ * to deal in the Software without restriction, including without limitation
1470+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1471+ * and/or sell copies of the Software, and to permit persons to whom the
1472+ * Software is furnished to do so, subject to the following conditions:
1473+ *
1474+ * The above copyright notice and this permission notice (including the next
1475+ * paragraph) shall be included in all copies or substantial portions of the
1476+ * Software.
1477+ *
1478+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1479+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1480+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1481+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1482+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1483+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
1484+ * IN THE SOFTWARE.
1485+ *
1486+ * Authors:
1487+ * Eric Anholt <eric@anholt.net>
1488+ *
1489+ */
1490+
1491+#include "drmP.h"
1492+#include "drm.h"
1493+#include "i915_drm.h"
1494+#include "i915_drv.h"
1495+#include <linux/swap.h>
1496+
1497+static int
1498+i915_gem_object_set_domain(struct drm_gem_object *obj,
1499+ uint32_t read_domains,
1500+ uint32_t write_domain);
1501+static int
1502+i915_gem_object_set_domain_range(struct drm_gem_object *obj,
1503+ uint64_t offset,
1504+ uint64_t size,
1505+ uint32_t read_domains,
1506+ uint32_t write_domain);
1507+static int
1508+i915_gem_set_domain(struct drm_gem_object *obj,
1509+ struct drm_file *file_priv,
1510+ uint32_t read_domains,
1511+ uint32_t write_domain);
1512+static int i915_gem_object_get_page_list(struct drm_gem_object *obj);
1513+static void i915_gem_object_free_page_list(struct drm_gem_object *obj);
1514+static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
1515+
1516+int
1517+i915_gem_init_ioctl(struct drm_device *dev, void *data,
1518+ struct drm_file *file_priv)
1519+{
1520+ drm_i915_private_t *dev_priv = dev->dev_private;
1521+ struct drm_i915_gem_init *args = data;
1522+
1523+ mutex_lock(&dev->struct_mutex);
1524+
1525+ if (args->gtt_start >= args->gtt_end ||
1526+ (args->gtt_start & (PAGE_SIZE - 1)) != 0 ||
1527+ (args->gtt_end & (PAGE_SIZE - 1)) != 0) {
1528+ mutex_unlock(&dev->struct_mutex);
1529+ return -EINVAL;
1530+ }
1531+
1532+ drm_mm_init(&dev_priv->mm.gtt_space, args->gtt_start,
1533+ args->gtt_end - args->gtt_start);
1534+
1535+ dev->gtt_total = (uint32_t) (args->gtt_end - args->gtt_start);
1536+
1537+ mutex_unlock(&dev->struct_mutex);
1538+
1539+ return 0;
1540+}
1541+
1542+
1543+/**
1544+ * Creates a new mm object and returns a handle to it.
1545+ */
1546+int
1547+i915_gem_create_ioctl(struct drm_device *dev, void *data,
1548+ struct drm_file *file_priv)
1549+{
1550+ struct drm_i915_gem_create *args = data;
1551+ struct drm_gem_object *obj;
1552+ int handle, ret;
1553+
1554+ args->size = roundup(args->size, PAGE_SIZE);
1555+
1556+ /* Allocate the new object */
1557+ obj = drm_gem_object_alloc(dev, args->size);
1558+ if (obj == NULL)
1559+ return -ENOMEM;
1560+
1561+ ret = drm_gem_handle_create(file_priv, obj, &handle);
1562+ mutex_lock(&dev->struct_mutex);
1563+ drm_gem_object_handle_unreference(obj);
1564+ mutex_unlock(&dev->struct_mutex);
1565+
1566+ if (ret)
1567+ return ret;
1568+
1569+ args->handle = handle;
1570+
1571+ return 0;
1572+}
1573+
1574+/**
1575+ * Reads data from the object referenced by handle.
1576+ *
1577+ * On error, the contents of *data are undefined.
1578+ */
1579+int
1580+i915_gem_pread_ioctl(struct drm_device *dev, void *data,
1581+ struct drm_file *file_priv)
1582+{
1583+ struct drm_i915_gem_pread *args = data;
1584+ struct drm_gem_object *obj;
1585+ struct drm_i915_gem_object *obj_priv;
1586+ ssize_t read;
1587+ loff_t offset;
1588+ int ret;
1589+
1590+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1591+ if (obj == NULL)
1592+ return -EBADF;
1593+ obj_priv = obj->driver_private;
1594+
1595+ /* Bounds check source.
1596+ *
1597+ * XXX: This could use review for overflow issues...
1598+ */
1599+ if (args->offset > obj->size || args->size > obj->size ||
1600+ args->offset + args->size > obj->size) {
1601+ drm_gem_object_unreference(obj);
1602+ return -EINVAL;
1603+ }
1604+
1605+ mutex_lock(&dev->struct_mutex);
1606+
1607+ ret = i915_gem_object_set_domain_range(obj, args->offset, args->size,
1608+ I915_GEM_DOMAIN_CPU, 0);
1609+ if (ret != 0) {
1610+ drm_gem_object_unreference(obj);
1611+ mutex_unlock(&dev->struct_mutex);
1612+ }
1613+
1614+ offset = args->offset;
1615+
1616+ read = vfs_read(obj->filp, (char __user *)(uintptr_t)args->data_ptr,
1617+ args->size, &offset);
1618+ if (read != args->size) {
1619+ drm_gem_object_unreference(obj);
1620+ mutex_unlock(&dev->struct_mutex);
1621+ if (read < 0)
1622+ return read;
1623+ else
1624+ return -EINVAL;
1625+ }
1626+
1627+ drm_gem_object_unreference(obj);
1628+ mutex_unlock(&dev->struct_mutex);
1629+
1630+ return 0;
1631+}
1632+
1633+static int
1634+i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
1635+ struct drm_i915_gem_pwrite *args,
1636+ struct drm_file *file_priv)
1637+{
1638+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1639+ ssize_t remain;
1640+ loff_t offset;
1641+ char __user *user_data;
1642+ char *vaddr;
1643+ int i, o, l;
1644+ int ret = 0;
1645+ unsigned long pfn;
1646+ unsigned long unwritten;
1647+
1648+ user_data = (char __user *) (uintptr_t) args->data_ptr;
1649+ remain = args->size;
1650+ if (!access_ok(VERIFY_READ, user_data, remain))
1651+ return -EFAULT;
1652+
1653+
1654+ mutex_lock(&dev->struct_mutex);
1655+ ret = i915_gem_object_pin(obj, 0);
1656+ if (ret) {
1657+ mutex_unlock(&dev->struct_mutex);
1658+ return ret;
1659+ }
1660+ ret = i915_gem_set_domain(obj, file_priv,
1661+ I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
1662+ if (ret)
1663+ goto fail;
1664+
1665+ obj_priv = obj->driver_private;
1666+ offset = obj_priv->gtt_offset + args->offset;
1667+ obj_priv->dirty = 1;
1668+
1669+ while (remain > 0) {
1670+ /* Operation in this page
1671+ *
1672+ * i = page number
1673+ * o = offset within page
1674+ * l = bytes to copy
1675+ */
1676+ i = offset >> PAGE_SHIFT;
1677+ o = offset & (PAGE_SIZE-1);
1678+ l = remain;
1679+ if ((o + l) > PAGE_SIZE)
1680+ l = PAGE_SIZE - o;
1681+
1682+ pfn = (dev->agp->base >> PAGE_SHIFT) + i;
1683+
1684+#ifdef DRM_KMAP_ATOMIC_PROT_PFN
1685+ /* kmap_atomic can't map IO pages on non-HIGHMEM kernels
1686+ */
1687+ vaddr = kmap_atomic_prot_pfn(pfn, KM_USER0,
1688+ __pgprot(__PAGE_KERNEL));
1689+#if WATCH_PWRITE
1690+ DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n",
1691+ i, o, l, pfn, vaddr);
1692+#endif
1693+ unwritten = __copy_from_user_inatomic_nocache(vaddr + o,
1694+ user_data, l);
1695+ kunmap_atomic(vaddr, KM_USER0);
1696+
1697+ if (unwritten)
1698+#endif
1699+ {
1700+ vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
1701+#if WATCH_PWRITE
1702+ DRM_INFO("pwrite slow i %d o %d l %d "
1703+ "pfn %ld vaddr %p\n",
1704+ i, o, l, pfn, vaddr);
1705+#endif
1706+ if (vaddr == NULL) {
1707+ ret = -EFAULT;
1708+ goto fail;
1709+ }
1710+ unwritten = __copy_from_user(vaddr + o, user_data, l);
1711+#if WATCH_PWRITE
1712+ DRM_INFO("unwritten %ld\n", unwritten);
1713+#endif
1714+ iounmap(vaddr);
1715+ if (unwritten) {
1716+ ret = -EFAULT;
1717+ goto fail;
1718+ }
1719+ }
1720+
1721+ remain -= l;
1722+ user_data += l;
1723+ offset += l;
1724+ }
1725+#if WATCH_PWRITE && 1
1726+ i915_gem_clflush_object(obj);
1727+ i915_gem_dump_object(obj, args->offset + args->size, __func__, ~0);
1728+ i915_gem_clflush_object(obj);
1729+#endif
1730+
1731+fail:
1732+ i915_gem_object_unpin(obj);
1733+ mutex_unlock(&dev->struct_mutex);
1734+
1735+ return ret;
1736+}
1737+
1738+int
1739+i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
1740+ struct drm_i915_gem_pwrite *args,
1741+ struct drm_file *file_priv)
1742+{
1743+ int ret;
1744+ loff_t offset;
1745+ ssize_t written;
1746+
1747+ mutex_lock(&dev->struct_mutex);
1748+
1749+ ret = i915_gem_set_domain(obj, file_priv,
1750+ I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
1751+ if (ret) {
1752+ mutex_unlock(&dev->struct_mutex);
1753+ return ret;
1754+ }
1755+
1756+ offset = args->offset;
1757+
1758+ written = vfs_write(obj->filp,
1759+ (char __user *)(uintptr_t) args->data_ptr,
1760+ args->size, &offset);
1761+ if (written != args->size) {
1762+ mutex_unlock(&dev->struct_mutex);
1763+ if (written < 0)
1764+ return written;
1765+ else
1766+ return -EINVAL;
1767+ }
1768+
1769+ mutex_unlock(&dev->struct_mutex);
1770+
1771+ return 0;
1772+}
1773+
1774+/**
1775+ * Writes data to the object referenced by handle.
1776+ *
1777+ * On error, the contents of the buffer that were to be modified are undefined.
1778+ */
1779+int
1780+i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
1781+ struct drm_file *file_priv)
1782+{
1783+ struct drm_i915_gem_pwrite *args = data;
1784+ struct drm_gem_object *obj;
1785+ struct drm_i915_gem_object *obj_priv;
1786+ int ret = 0;
1787+
1788+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1789+ if (obj == NULL)
1790+ return -EBADF;
1791+ obj_priv = obj->driver_private;
1792+
1793+ /* Bounds check destination.
1794+ *
1795+ * XXX: This could use review for overflow issues...
1796+ */
1797+ if (args->offset > obj->size || args->size > obj->size ||
1798+ args->offset + args->size > obj->size) {
1799+ drm_gem_object_unreference(obj);
1800+ return -EINVAL;
1801+ }
1802+
1803+ /* We can only do the GTT pwrite on untiled buffers, as otherwise
1804+ * it would end up going through the fenced access, and we'll get
1805+ * different detiling behavior between reading and writing.
1806+ * pread/pwrite currently are reading and writing from the CPU
1807+ * perspective, requiring manual detiling by the client.
1808+ */
1809+ if (obj_priv->tiling_mode == I915_TILING_NONE &&
1810+ dev->gtt_total != 0)
1811+ ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv);
1812+ else
1813+ ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv);
1814+
1815+#if WATCH_PWRITE
1816+ if (ret)
1817+ DRM_INFO("pwrite failed %d\n", ret);
1818+#endif
1819+
1820+ drm_gem_object_unreference(obj);
1821+
1822+ return ret;
1823+}
1824+
1825+/**
1826+ * Called when user space prepares to use an object
1827+ */
1828+int
1829+i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1830+ struct drm_file *file_priv)
1831+{
1832+ struct drm_i915_gem_set_domain *args = data;
1833+ struct drm_gem_object *obj;
1834+ int ret;
1835+
1836+ if (!(dev->driver->driver_features & DRIVER_GEM))
1837+ return -ENODEV;
1838+
1839+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1840+ if (obj == NULL)
1841+ return -EBADF;
1842+
1843+ mutex_lock(&dev->struct_mutex);
1844+#if WATCH_BUF
1845+ DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n",
1846+ obj, obj->size, args->read_domains, args->write_domain);
1847+#endif
1848+ ret = i915_gem_set_domain(obj, file_priv,
1849+ args->read_domains, args->write_domain);
1850+ drm_gem_object_unreference(obj);
1851+ mutex_unlock(&dev->struct_mutex);
1852+ return ret;
1853+}
1854+
1855+/**
1856+ * Called when user space has done writes to this buffer
1857+ */
1858+int
1859+i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
1860+ struct drm_file *file_priv)
1861+{
1862+ struct drm_i915_gem_sw_finish *args = data;
1863+ struct drm_gem_object *obj;
1864+ struct drm_i915_gem_object *obj_priv;
1865+ int ret = 0;
1866+
1867+ if (!(dev->driver->driver_features & DRIVER_GEM))
1868+ return -ENODEV;
1869+
1870+ mutex_lock(&dev->struct_mutex);
1871+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1872+ if (obj == NULL) {
1873+ mutex_unlock(&dev->struct_mutex);
1874+ return -EBADF;
1875+ }
1876+
1877+#if WATCH_BUF
1878+ DRM_INFO("%s: sw_finish %d (%p %d)\n",
1879+ __func__, args->handle, obj, obj->size);
1880+#endif
1881+ obj_priv = obj->driver_private;
1882+
1883+ /* Pinned buffers may be scanout, so flush the cache */
1884+ if ((obj->write_domain & I915_GEM_DOMAIN_CPU) && obj_priv->pin_count) {
1885+ i915_gem_clflush_object(obj);
1886+ drm_agp_chipset_flush(dev);
1887+ }
1888+ drm_gem_object_unreference(obj);
1889+ mutex_unlock(&dev->struct_mutex);
1890+ return ret;
1891+}
1892+
1893+/**
1894+ * Maps the contents of an object, returning the address it is mapped
1895+ * into.
1896+ *
1897+ * While the mapping holds a reference on the contents of the object, it doesn't
1898+ * imply a ref on the object itself.
1899+ */
1900+int
1901+i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
1902+ struct drm_file *file_priv)
1903+{
1904+ struct drm_i915_gem_mmap *args = data;
1905+ struct drm_gem_object *obj;
1906+ loff_t offset;
1907+ unsigned long addr;
1908+
1909+ if (!(dev->driver->driver_features & DRIVER_GEM))
1910+ return -ENODEV;
1911+
1912+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1913+ if (obj == NULL)
1914+ return -EBADF;
1915+
1916+ offset = args->offset;
1917+
1918+ down_write(&current->mm->mmap_sem);
1919+ addr = do_mmap(obj->filp, 0, args->size,
1920+ PROT_READ | PROT_WRITE, MAP_SHARED,
1921+ args->offset);
1922+ up_write(&current->mm->mmap_sem);
1923+ mutex_lock(&dev->struct_mutex);
1924+ drm_gem_object_unreference(obj);
1925+ mutex_unlock(&dev->struct_mutex);
1926+ if (IS_ERR((void *)addr))
1927+ return addr;
1928+
1929+ args->addr_ptr = (uint64_t) addr;
1930+
1931+ return 0;
1932+}
1933+
1934+static void
1935+i915_gem_object_free_page_list(struct drm_gem_object *obj)
1936+{
1937+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1938+ int page_count = obj->size / PAGE_SIZE;
1939+ int i;
1940+
1941+ if (obj_priv->page_list == NULL)
1942+ return;
1943+
1944+
1945+ for (i = 0; i < page_count; i++)
1946+ if (obj_priv->page_list[i] != NULL) {
1947+ if (obj_priv->dirty)
1948+ set_page_dirty(obj_priv->page_list[i]);
1949+ mark_page_accessed(obj_priv->page_list[i]);
1950+ page_cache_release(obj_priv->page_list[i]);
1951+ }
1952+ obj_priv->dirty = 0;
1953+
1954+ drm_free(obj_priv->page_list,
1955+ page_count * sizeof(struct page *),
1956+ DRM_MEM_DRIVER);
1957+ obj_priv->page_list = NULL;
1958+}
1959+
1960+static void
1961+i915_gem_object_move_to_active(struct drm_gem_object *obj)
1962+{
1963+ struct drm_device *dev = obj->dev;
1964+ drm_i915_private_t *dev_priv = dev->dev_private;
1965+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1966+
1967+ /* Add a reference if we're newly entering the active list. */
1968+ if (!obj_priv->active) {
1969+ drm_gem_object_reference(obj);
1970+ obj_priv->active = 1;
1971+ }
1972+ /* Move from whatever list we were on to the tail of execution. */
1973+ list_move_tail(&obj_priv->list,
1974+ &dev_priv->mm.active_list);
1975+}
1976+
1977+
1978+static void
1979+i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
1980+{
1981+ struct drm_device *dev = obj->dev;
1982+ drm_i915_private_t *dev_priv = dev->dev_private;
1983+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1984+
1985+ i915_verify_inactive(dev, __FILE__, __LINE__);
1986+ if (obj_priv->pin_count != 0)
1987+ list_del_init(&obj_priv->list);
1988+ else
1989+ list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
1990+
1991+ if (obj_priv->active) {
1992+ obj_priv->active = 0;
1993+ drm_gem_object_unreference(obj);
1994+ }
1995+ i915_verify_inactive(dev, __FILE__, __LINE__);
1996+}
1997+
1998+/**
1999+ * Creates a new sequence number, emitting a write of it to the status page
2000+ * plus an interrupt, which will trigger i915_user_interrupt_handler.
2001+ *
2002+ * Must be called with struct_lock held.
2003+ *
2004+ * Returned sequence numbers are nonzero on success.
2005+ */
2006+static uint32_t
2007+i915_add_request(struct drm_device *dev, uint32_t flush_domains)
2008+{
2009+ drm_i915_private_t *dev_priv = dev->dev_private;
2010+ struct drm_i915_gem_request *request;
2011+ uint32_t seqno;
2012+ int was_empty;
2013+ RING_LOCALS;
2014+
2015+ request = drm_calloc(1, sizeof(*request), DRM_MEM_DRIVER);
2016+ if (request == NULL)
2017+ return 0;
2018+
2019+ /* Grab the seqno we're going to make this request be, and bump the
2020+ * next (skipping 0 so it can be the reserved no-seqno value).
2021+ */
2022+ seqno = dev_priv->mm.next_gem_seqno;
2023+ dev_priv->mm.next_gem_seqno++;
2024+ if (dev_priv->mm.next_gem_seqno == 0)
2025+ dev_priv->mm.next_gem_seqno++;
2026+
2027+ BEGIN_LP_RING(4);
2028+ OUT_RING(MI_STORE_DWORD_INDEX);
2029+ OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
2030+ OUT_RING(seqno);
2031+
2032+ OUT_RING(MI_USER_INTERRUPT);
2033+ ADVANCE_LP_RING();
2034+
2035+ DRM_DEBUG("%d\n", seqno);
2036+
2037+ request->seqno = seqno;
2038+ request->emitted_jiffies = jiffies;
2039+ request->flush_domains = flush_domains;
2040+ was_empty = list_empty(&dev_priv->mm.request_list);
2041+ list_add_tail(&request->list, &dev_priv->mm.request_list);
2042+
2043+ if (was_empty)
2044+ schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
2045+ return seqno;
2046+}
2047+
2048+/**
2049+ * Command execution barrier
2050+ *
2051+ * Ensures that all commands in the ring are finished
2052+ * before signalling the CPU
2053+ */
2054+uint32_t
2055+i915_retire_commands(struct drm_device *dev)
2056+{
2057+ drm_i915_private_t *dev_priv = dev->dev_private;
2058+ uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
2059+ uint32_t flush_domains = 0;
2060+ RING_LOCALS;
2061+
2062+ /* The sampler always gets flushed on i965 (sigh) */
2063+ if (IS_I965G(dev))
2064+ flush_domains |= I915_GEM_DOMAIN_SAMPLER;
2065+ BEGIN_LP_RING(2);
2066+ OUT_RING(cmd);
2067+ OUT_RING(0); /* noop */
2068+ ADVANCE_LP_RING();
2069+ return flush_domains;
2070+}
2071+
2072+/**
2073+ * Moves buffers associated only with the given active seqno from the active
2074+ * to inactive list, potentially freeing them.
2075+ */
2076+static void
2077+i915_gem_retire_request(struct drm_device *dev,
2078+ struct drm_i915_gem_request *request)
2079+{
2080+ drm_i915_private_t *dev_priv = dev->dev_private;
2081+
2082+ /* Move any buffers on the active list that are no longer referenced
2083+ * by the ringbuffer to the flushing/inactive lists as appropriate.
2084+ */
2085+ while (!list_empty(&dev_priv->mm.active_list)) {
2086+ struct drm_gem_object *obj;
2087+ struct drm_i915_gem_object *obj_priv;
2088+
2089+ obj_priv = list_first_entry(&dev_priv->mm.active_list,
2090+ struct drm_i915_gem_object,
2091+ list);
2092+ obj = obj_priv->obj;
2093+
2094+ /* If the seqno being retired doesn't match the oldest in the
2095+ * list, then the oldest in the list must still be newer than
2096+ * this seqno.
2097+ */
2098+ if (obj_priv->last_rendering_seqno != request->seqno)
2099+ return;
2100+#if WATCH_LRU
2101+ DRM_INFO("%s: retire %d moves to inactive list %p\n",
2102+ __func__, request->seqno, obj);
2103+#endif
2104+
2105+ if (obj->write_domain != 0) {
2106+ list_move_tail(&obj_priv->list,
2107+ &dev_priv->mm.flushing_list);
2108+ } else {
2109+ i915_gem_object_move_to_inactive(obj);
2110+ }
2111+ }
2112+
2113+ if (request->flush_domains != 0) {
2114+ struct drm_i915_gem_object *obj_priv, *next;
2115+
2116+ /* Clear the write domain and activity from any buffers
2117+ * that are just waiting for a flush matching the one retired.
2118+ */
2119+ list_for_each_entry_safe(obj_priv, next,
2120+ &dev_priv->mm.flushing_list, list) {
2121+ struct drm_gem_object *obj = obj_priv->obj;
2122+
2123+ if (obj->write_domain & request->flush_domains) {
2124+ obj->write_domain = 0;
2125+ i915_gem_object_move_to_inactive(obj);
2126+ }
2127+ }
2128+
2129+ }
2130+}
2131+
2132+/**
2133+ * Returns true if seq1 is later than seq2.
2134+ */
2135+static int
2136+i915_seqno_passed(uint32_t seq1, uint32_t seq2)
2137+{
2138+ return (int32_t)(seq1 - seq2) >= 0;
2139+}
2140+
2141+uint32_t
2142+i915_get_gem_seqno(struct drm_device *dev)
2143+{
2144+ drm_i915_private_t *dev_priv = dev->dev_private;
2145+
2146+ return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
2147+}
2148+
2149+/**
2150+ * This function clears the request list as sequence numbers are passed.
2151+ */
2152+void
2153+i915_gem_retire_requests(struct drm_device *dev)
2154+{
2155+ drm_i915_private_t *dev_priv = dev->dev_private;
2156+ uint32_t seqno;
2157+
2158+ seqno = i915_get_gem_seqno(dev);
2159+
2160+ while (!list_empty(&dev_priv->mm.request_list)) {
2161+ struct drm_i915_gem_request *request;
2162+ uint32_t retiring_seqno;
2163+
2164+ request = list_first_entry(&dev_priv->mm.request_list,
2165+ struct drm_i915_gem_request,
2166+ list);
2167+ retiring_seqno = request->seqno;
2168+
2169+ if (i915_seqno_passed(seqno, retiring_seqno) ||
2170+ dev_priv->mm.wedged) {
2171+ i915_gem_retire_request(dev, request);
2172+
2173+ list_del(&request->list);
2174+ drm_free(request, sizeof(*request), DRM_MEM_DRIVER);
2175+ } else
2176+ break;
2177+ }
2178+}
2179+
2180+void
2181+i915_gem_retire_work_handler(struct work_struct *work)
2182+{
2183+ drm_i915_private_t *dev_priv;
2184+ struct drm_device *dev;
2185+
2186+ dev_priv = container_of(work, drm_i915_private_t,
2187+ mm.retire_work.work);
2188+ dev = dev_priv->dev;
2189+
2190+ mutex_lock(&dev->struct_mutex);
2191+ i915_gem_retire_requests(dev);
2192+ if (!list_empty(&dev_priv->mm.request_list))
2193+ schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
2194+ mutex_unlock(&dev->struct_mutex);
2195+}
2196+
2197+/**
2198+ * Waits for a sequence number to be signaled, and cleans up the
2199+ * request and object lists appropriately for that event.
2200+ */
2201+int
2202+i915_wait_request(struct drm_device *dev, uint32_t seqno)
2203+{
2204+ drm_i915_private_t *dev_priv = dev->dev_private;
2205+ int ret = 0;
2206+
2207+ BUG_ON(seqno == 0);
2208+
2209+ if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
2210+ dev_priv->mm.waiting_gem_seqno = seqno;
2211+ i915_user_irq_get(dev);
2212+ ret = wait_event_interruptible(dev_priv->irq_queue,
2213+ i915_seqno_passed(i915_get_gem_seqno(dev),
2214+ seqno) ||
2215+ dev_priv->mm.wedged);
2216+ i915_user_irq_put(dev);
2217+ dev_priv->mm.waiting_gem_seqno = 0;
2218+ }
2219+ if (dev_priv->mm.wedged)
2220+ ret = -EIO;
2221+
2222+ if (ret && ret != -ERESTARTSYS)
2223+ DRM_ERROR("%s returns %d (awaiting %d at %d)\n",
2224+ __func__, ret, seqno, i915_get_gem_seqno(dev));
2225+
2226+ /* Directly dispatch request retiring. While we have the work queue
2227+ * to handle this, the waiter on a request often wants an associated
2228+ * buffer to have made it to the inactive list, and we would need
2229+ * a separate wait queue to handle that.
2230+ */
2231+ if (ret == 0)
2232+ i915_gem_retire_requests(dev);
2233+
2234+ return ret;
2235+}
2236+
2237+static void
2238+i915_gem_flush(struct drm_device *dev,
2239+ uint32_t invalidate_domains,
2240+ uint32_t flush_domains)
2241+{
2242+ drm_i915_private_t *dev_priv = dev->dev_private;
2243+ uint32_t cmd;
2244+ RING_LOCALS;
2245+
2246+#if WATCH_EXEC
2247+ DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
2248+ invalidate_domains, flush_domains);
2249+#endif
2250+
2251+ if (flush_domains & I915_GEM_DOMAIN_CPU)
2252+ drm_agp_chipset_flush(dev);
2253+
2254+ if ((invalidate_domains | flush_domains) & ~(I915_GEM_DOMAIN_CPU |
2255+ I915_GEM_DOMAIN_GTT)) {
2256+ /*
2257+ * read/write caches:
2258+ *
2259+ * I915_GEM_DOMAIN_RENDER is always invalidated, but is
2260+ * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is
2261+ * also flushed at 2d versus 3d pipeline switches.
2262+ *
2263+ * read-only caches:
2264+ *
2265+ * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
2266+ * MI_READ_FLUSH is set, and is always flushed on 965.
2267+ *
2268+ * I915_GEM_DOMAIN_COMMAND may not exist?
2269+ *
2270+ * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
2271+ * invalidated when MI_EXE_FLUSH is set.
2272+ *
2273+ * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
2274+ * invalidated with every MI_FLUSH.
2275+ *
2276+ * TLBs:
2277+ *
2278+ * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
2279+ * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
2280+ * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
2281+ * are flushed at any MI_FLUSH.
2282+ */
2283+
2284+ cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
2285+ if ((invalidate_domains|flush_domains) &
2286+ I915_GEM_DOMAIN_RENDER)
2287+ cmd &= ~MI_NO_WRITE_FLUSH;
2288+ if (!IS_I965G(dev)) {
2289+ /*
2290+ * On the 965, the sampler cache always gets flushed
2291+ * and this bit is reserved.
2292+ */
2293+ if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
2294+ cmd |= MI_READ_FLUSH;
2295+ }
2296+ if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
2297+ cmd |= MI_EXE_FLUSH;
2298+
2299+#if WATCH_EXEC
2300+ DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
2301+#endif
2302+ BEGIN_LP_RING(2);
2303+ OUT_RING(cmd);
2304+ OUT_RING(0); /* noop */
2305+ ADVANCE_LP_RING();
2306+ }
2307+}
2308+
2309+/**
2310+ * Ensures that all rendering to the object has completed and the object is
2311+ * safe to unbind from the GTT or access from the CPU.
2312+ */
2313+static int
2314+i915_gem_object_wait_rendering(struct drm_gem_object *obj)
2315+{
2316+ struct drm_device *dev = obj->dev;
2317+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2318+ int ret;
2319+
2320+ /* If there are writes queued to the buffer, flush and
2321+ * create a new seqno to wait for.
2322+ */
2323+ if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) {
2324+ uint32_t write_domain = obj->write_domain;
2325+#if WATCH_BUF
2326+ DRM_INFO("%s: flushing object %p from write domain %08x\n",
2327+ __func__, obj, write_domain);
2328+#endif
2329+ i915_gem_flush(dev, 0, write_domain);
2330+
2331+ i915_gem_object_move_to_active(obj);
2332+ obj_priv->last_rendering_seqno = i915_add_request(dev,
2333+ write_domain);
2334+ BUG_ON(obj_priv->last_rendering_seqno == 0);
2335+#if WATCH_LRU
2336+ DRM_INFO("%s: flush moves to exec list %p\n", __func__, obj);
2337+#endif
2338+ }
2339+
2340+ /* If there is rendering queued on the buffer being evicted, wait for
2341+ * it.
2342+ */
2343+ if (obj_priv->active) {
2344+#if WATCH_BUF
2345+ DRM_INFO("%s: object %p wait for seqno %08x\n",
2346+ __func__, obj, obj_priv->last_rendering_seqno);
2347+#endif
2348+ ret = i915_wait_request(dev, obj_priv->last_rendering_seqno);
2349+ if (ret != 0)
2350+ return ret;
2351+ }
2352+
2353+ return 0;
2354+}
2355+
2356+/**
2357+ * Unbinds an object from the GTT aperture.
2358+ */
2359+static int
2360+i915_gem_object_unbind(struct drm_gem_object *obj)
2361+{
2362+ struct drm_device *dev = obj->dev;
2363+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2364+ int ret = 0;
2365+
2366+#if WATCH_BUF
2367+ DRM_INFO("%s:%d %p\n", __func__, __LINE__, obj);
2368+ DRM_INFO("gtt_space %p\n", obj_priv->gtt_space);
2369+#endif
2370+ if (obj_priv->gtt_space == NULL)
2371+ return 0;
2372+
2373+ if (obj_priv->pin_count != 0) {
2374+ DRM_ERROR("Attempting to unbind pinned buffer\n");
2375+ return -EINVAL;
2376+ }
2377+
2378+ /* Wait for any rendering to complete
2379+ */
2380+ ret = i915_gem_object_wait_rendering(obj);
2381+ if (ret) {
2382+ DRM_ERROR("wait_rendering failed: %d\n", ret);
2383+ return ret;
2384+ }
2385+
2386+ /* Move the object to the CPU domain to ensure that
2387+ * any possible CPU writes while it's not in the GTT
2388+ * are flushed when we go to remap it. This will
2389+ * also ensure that all pending GPU writes are finished
2390+ * before we unbind.
2391+ */
2392+ ret = i915_gem_object_set_domain(obj, I915_GEM_DOMAIN_CPU,
2393+ I915_GEM_DOMAIN_CPU);
2394+ if (ret) {
2395+ DRM_ERROR("set_domain failed: %d\n", ret);
2396+ return ret;
2397+ }
2398+
2399+ if (obj_priv->agp_mem != NULL) {
2400+ drm_unbind_agp(obj_priv->agp_mem);
2401+ drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE);
2402+ obj_priv->agp_mem = NULL;
2403+ }
2404+
2405+ BUG_ON(obj_priv->active);
2406+
2407+ i915_gem_object_free_page_list(obj);
2408+
2409+ if (obj_priv->gtt_space) {
2410+ atomic_dec(&dev->gtt_count);
2411+ atomic_sub(obj->size, &dev->gtt_memory);
2412+
2413+ drm_mm_put_block(obj_priv->gtt_space);
2414+ obj_priv->gtt_space = NULL;
2415+ }
2416+
2417+ /* Remove ourselves from the LRU list if present. */
2418+ if (!list_empty(&obj_priv->list))
2419+ list_del_init(&obj_priv->list);
2420+
2421+ return 0;
2422+}
2423+
2424+static int
2425+i915_gem_evict_something(struct drm_device *dev)
2426+{
2427+ drm_i915_private_t *dev_priv = dev->dev_private;
2428+ struct drm_gem_object *obj;
2429+ struct drm_i915_gem_object *obj_priv;
2430+ int ret = 0;
2431+
2432+ for (;;) {
2433+ /* If there's an inactive buffer available now, grab it
2434+ * and be done.
2435+ */
2436+ if (!list_empty(&dev_priv->mm.inactive_list)) {
2437+ obj_priv = list_first_entry(&dev_priv->mm.inactive_list,
2438+ struct drm_i915_gem_object,
2439+ list);
2440+ obj = obj_priv->obj;
2441+ BUG_ON(obj_priv->pin_count != 0);
2442+#if WATCH_LRU
2443+ DRM_INFO("%s: evicting %p\n", __func__, obj);
2444+#endif
2445+ BUG_ON(obj_priv->active);
2446+
2447+ /* Wait on the rendering and unbind the buffer. */
2448+ ret = i915_gem_object_unbind(obj);
2449+ break;
2450+ }
2451+
2452+ /* If we didn't get anything, but the ring is still processing
2453+ * things, wait for one of those things to finish and hopefully
2454+ * leave us a buffer to evict.
2455+ */
2456+ if (!list_empty(&dev_priv->mm.request_list)) {
2457+ struct drm_i915_gem_request *request;
2458+
2459+ request = list_first_entry(&dev_priv->mm.request_list,
2460+ struct drm_i915_gem_request,
2461+ list);
2462+
2463+ ret = i915_wait_request(dev, request->seqno);
2464+ if (ret)
2465+ break;
2466+
2467+ /* if waiting caused an object to become inactive,
2468+ * then loop around and wait for it. Otherwise, we
2469+ * assume that waiting freed and unbound something,
2470+ * so there should now be some space in the GTT
2471+ */
2472+ if (!list_empty(&dev_priv->mm.inactive_list))
2473+ continue;
2474+ break;
2475+ }
2476+
2477+ /* If we didn't have anything on the request list but there
2478+ * are buffers awaiting a flush, emit one and try again.
2479+ * When we wait on it, those buffers waiting for that flush
2480+ * will get moved to inactive.
2481+ */
2482+ if (!list_empty(&dev_priv->mm.flushing_list)) {
2483+ obj_priv = list_first_entry(&dev_priv->mm.flushing_list,
2484+ struct drm_i915_gem_object,
2485+ list);
2486+ obj = obj_priv->obj;
2487+
2488+ i915_gem_flush(dev,
2489+ obj->write_domain,
2490+ obj->write_domain);
2491+ i915_add_request(dev, obj->write_domain);
2492+
2493+ obj = NULL;
2494+ continue;
2495+ }
2496+
2497+ DRM_ERROR("inactive empty %d request empty %d "
2498+ "flushing empty %d\n",
2499+ list_empty(&dev_priv->mm.inactive_list),
2500+ list_empty(&dev_priv->mm.request_list),
2501+ list_empty(&dev_priv->mm.flushing_list));
2502+ /* If we didn't do any of the above, there's nothing to be done
2503+ * and we just can't fit it in.
2504+ */
2505+ return -ENOMEM;
2506+ }
2507+ return ret;
2508+}
2509+
2510+static int
2511+i915_gem_object_get_page_list(struct drm_gem_object *obj)
2512+{
2513+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2514+ int page_count, i;
2515+ struct address_space *mapping;
2516+ struct inode *inode;
2517+ struct page *page;
2518+ int ret;
2519+
2520+ if (obj_priv->page_list)
2521+ return 0;
2522+
2523+ /* Get the list of pages out of our struct file. They'll be pinned
2524+ * at this point until we release them.
2525+ */
2526+ page_count = obj->size / PAGE_SIZE;
2527+ BUG_ON(obj_priv->page_list != NULL);
2528+ obj_priv->page_list = drm_calloc(page_count, sizeof(struct page *),
2529+ DRM_MEM_DRIVER);
2530+ if (obj_priv->page_list == NULL) {
2531+ DRM_ERROR("Faled to allocate page list\n");
2532+ return -ENOMEM;
2533+ }
2534+
2535+ inode = obj->filp->f_path.dentry->d_inode;
2536+ mapping = inode->i_mapping;
2537+ for (i = 0; i < page_count; i++) {
2538+ page = read_mapping_page(mapping, i, NULL);
2539+ if (IS_ERR(page)) {
2540+ ret = PTR_ERR(page);
2541+ DRM_ERROR("read_mapping_page failed: %d\n", ret);
2542+ i915_gem_object_free_page_list(obj);
2543+ return ret;
2544+ }
2545+ obj_priv->page_list[i] = page;
2546+ }
2547+ return 0;
2548+}
2549+
2550+/**
2551+ * Finds free space in the GTT aperture and binds the object there.
2552+ */
2553+static int
2554+i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2555+{
2556+ struct drm_device *dev = obj->dev;
2557+ drm_i915_private_t *dev_priv = dev->dev_private;
2558+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2559+ struct drm_mm_node *free_space;
2560+ int page_count, ret;
2561+
2562+ if (alignment == 0)
2563+ alignment = PAGE_SIZE;
2564+ if (alignment & (PAGE_SIZE - 1)) {
2565+ DRM_ERROR("Invalid object alignment requested %u\n", alignment);
2566+ return -EINVAL;
2567+ }
2568+
2569+ search_free:
2570+ free_space = drm_mm_search_free(&dev_priv->mm.gtt_space,
2571+ obj->size, alignment, 0);
2572+ if (free_space != NULL) {
2573+ obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size,
2574+ alignment);
2575+ if (obj_priv->gtt_space != NULL) {
2576+ obj_priv->gtt_space->private = obj;
2577+ obj_priv->gtt_offset = obj_priv->gtt_space->start;
2578+ }
2579+ }
2580+ if (obj_priv->gtt_space == NULL) {
2581+ /* If the gtt is empty and we're still having trouble
2582+ * fitting our object in, we're out of memory.
2583+ */
2584+#if WATCH_LRU
2585+ DRM_INFO("%s: GTT full, evicting something\n", __func__);
2586+#endif
2587+ if (list_empty(&dev_priv->mm.inactive_list) &&
2588+ list_empty(&dev_priv->mm.flushing_list) &&
2589+ list_empty(&dev_priv->mm.active_list)) {
2590+ DRM_ERROR("GTT full, but LRU list empty\n");
2591+ return -ENOMEM;
2592+ }
2593+
2594+ ret = i915_gem_evict_something(dev);
2595+ if (ret != 0) {
2596+ DRM_ERROR("Failed to evict a buffer %d\n", ret);
2597+ return ret;
2598+ }
2599+ goto search_free;
2600+ }
2601+
2602+#if WATCH_BUF
2603+ DRM_INFO("Binding object of size %d at 0x%08x\n",
2604+ obj->size, obj_priv->gtt_offset);
2605+#endif
2606+ ret = i915_gem_object_get_page_list(obj);
2607+ if (ret) {
2608+ drm_mm_put_block(obj_priv->gtt_space);
2609+ obj_priv->gtt_space = NULL;
2610+ return ret;
2611+ }
2612+
2613+ page_count = obj->size / PAGE_SIZE;
2614+ /* Create an AGP memory structure pointing at our pages, and bind it
2615+ * into the GTT.
2616+ */
2617+ obj_priv->agp_mem = drm_agp_bind_pages(dev,
2618+ obj_priv->page_list,
2619+ page_count,
2620+ obj_priv->gtt_offset);
2621+ if (obj_priv->agp_mem == NULL) {
2622+ i915_gem_object_free_page_list(obj);
2623+ drm_mm_put_block(obj_priv->gtt_space);
2624+ obj_priv->gtt_space = NULL;
2625+ return -ENOMEM;
2626+ }
2627+ atomic_inc(&dev->gtt_count);
2628+ atomic_add(obj->size, &dev->gtt_memory);
2629+
2630+ /* Assert that the object is not currently in any GPU domain. As it
2631+ * wasn't in the GTT, there shouldn't be any way it could have been in
2632+ * a GPU cache
2633+ */
2634+ BUG_ON(obj->read_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
2635+ BUG_ON(obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
2636+
2637+ return 0;
2638+}
2639+
2640+void
2641+i915_gem_clflush_object(struct drm_gem_object *obj)
2642+{
2643+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2644+
2645+ /* If we don't have a page list set up, then we're not pinned
2646+ * to GPU, and we can ignore the cache flush because it'll happen
2647+ * again at bind time.
2648+ */
2649+ if (obj_priv->page_list == NULL)
2650+ return;
2651+
2652+ drm_clflush_pages(obj_priv->page_list, obj->size / PAGE_SIZE);
2653+}
2654+
2655+/*
2656+ * Set the next domain for the specified object. This
2657+ * may not actually perform the necessary flushing/invaliding though,
2658+ * as that may want to be batched with other set_domain operations
2659+ *
2660+ * This is (we hope) the only really tricky part of gem. The goal
2661+ * is fairly simple -- track which caches hold bits of the object
2662+ * and make sure they remain coherent. A few concrete examples may
2663+ * help to explain how it works. For shorthand, we use the notation
2664+ * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the
2665+ * a pair of read and write domain masks.
2666+ *
2667+ * Case 1: the batch buffer
2668+ *
2669+ * 1. Allocated
2670+ * 2. Written by CPU
2671+ * 3. Mapped to GTT
2672+ * 4. Read by GPU
2673+ * 5. Unmapped from GTT
2674+ * 6. Freed
2675+ *
2676+ * Let's take these a step at a time
2677+ *
2678+ * 1. Allocated
2679+ * Pages allocated from the kernel may still have
2680+ * cache contents, so we set them to (CPU, CPU) always.
2681+ * 2. Written by CPU (using pwrite)
2682+ * The pwrite function calls set_domain (CPU, CPU) and
2683+ * this function does nothing (as nothing changes)
2684+ * 3. Mapped by GTT
2685+ * This function asserts that the object is not
2686+ * currently in any GPU-based read or write domains
2687+ * 4. Read by GPU
2688+ * i915_gem_execbuffer calls set_domain (COMMAND, 0).
2689+ * As write_domain is zero, this function adds in the
2690+ * current read domains (CPU+COMMAND, 0).
2691+ * flush_domains is set to CPU.
2692+ * invalidate_domains is set to COMMAND
2693+ * clflush is run to get data out of the CPU caches
2694+ * then i915_dev_set_domain calls i915_gem_flush to
2695+ * emit an MI_FLUSH and drm_agp_chipset_flush
2696+ * 5. Unmapped from GTT
2697+ * i915_gem_object_unbind calls set_domain (CPU, CPU)
2698+ * flush_domains and invalidate_domains end up both zero
2699+ * so no flushing/invalidating happens
2700+ * 6. Freed
2701+ * yay, done
2702+ *
2703+ * Case 2: The shared render buffer
2704+ *
2705+ * 1. Allocated
2706+ * 2. Mapped to GTT
2707+ * 3. Read/written by GPU
2708+ * 4. set_domain to (CPU,CPU)
2709+ * 5. Read/written by CPU
2710+ * 6. Read/written by GPU
2711+ *
2712+ * 1. Allocated
2713+ * Same as last example, (CPU, CPU)
2714+ * 2. Mapped to GTT
2715+ * Nothing changes (assertions find that it is not in the GPU)
2716+ * 3. Read/written by GPU
2717+ * execbuffer calls set_domain (RENDER, RENDER)
2718+ * flush_domains gets CPU
2719+ * invalidate_domains gets GPU
2720+ * clflush (obj)
2721+ * MI_FLUSH and drm_agp_chipset_flush
2722+ * 4. set_domain (CPU, CPU)
2723+ * flush_domains gets GPU
2724+ * invalidate_domains gets CPU
2725+ * wait_rendering (obj) to make sure all drawing is complete.
2726+ * This will include an MI_FLUSH to get the data from GPU
2727+ * to memory
2728+ * clflush (obj) to invalidate the CPU cache
2729+ * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?)
2730+ * 5. Read/written by CPU
2731+ * cache lines are loaded and dirtied
2732+ * 6. Read written by GPU
2733+ * Same as last GPU access
2734+ *
2735+ * Case 3: The constant buffer
2736+ *
2737+ * 1. Allocated
2738+ * 2. Written by CPU
2739+ * 3. Read by GPU
2740+ * 4. Updated (written) by CPU again
2741+ * 5. Read by GPU
2742+ *
2743+ * 1. Allocated
2744+ * (CPU, CPU)
2745+ * 2. Written by CPU
2746+ * (CPU, CPU)
2747+ * 3. Read by GPU
2748+ * (CPU+RENDER, 0)
2749+ * flush_domains = CPU
2750+ * invalidate_domains = RENDER
2751+ * clflush (obj)
2752+ * MI_FLUSH
2753+ * drm_agp_chipset_flush
2754+ * 4. Updated (written) by CPU again
2755+ * (CPU, CPU)
2756+ * flush_domains = 0 (no previous write domain)
2757+ * invalidate_domains = 0 (no new read domains)
2758+ * 5. Read by GPU
2759+ * (CPU+RENDER, 0)
2760+ * flush_domains = CPU
2761+ * invalidate_domains = RENDER
2762+ * clflush (obj)
2763+ * MI_FLUSH
2764+ * drm_agp_chipset_flush
2765+ */
2766+static int
2767+i915_gem_object_set_domain(struct drm_gem_object *obj,
2768+ uint32_t read_domains,
2769+ uint32_t write_domain)
2770+{
2771+ struct drm_device *dev = obj->dev;
2772+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2773+ uint32_t invalidate_domains = 0;
2774+ uint32_t flush_domains = 0;
2775+ int ret;
2776+
2777+#if WATCH_BUF
2778+ DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
2779+ __func__, obj,
2780+ obj->read_domains, read_domains,
2781+ obj->write_domain, write_domain);
2782+#endif
2783+ /*
2784+ * If the object isn't moving to a new write domain,
2785+ * let the object stay in multiple read domains
2786+ */
2787+ if (write_domain == 0)
2788+ read_domains |= obj->read_domains;
2789+ else
2790+ obj_priv->dirty = 1;
2791+
2792+ /*
2793+ * Flush the current write domain if
2794+ * the new read domains don't match. Invalidate
2795+ * any read domains which differ from the old
2796+ * write domain
2797+ */
2798+ if (obj->write_domain && obj->write_domain != read_domains) {
2799+ flush_domains |= obj->write_domain;
2800+ invalidate_domains |= read_domains & ~obj->write_domain;
2801+ }
2802+ /*
2803+ * Invalidate any read caches which may have
2804+ * stale data. That is, any new read domains.
2805+ */
2806+ invalidate_domains |= read_domains & ~obj->read_domains;
2807+ if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) {
2808+#if WATCH_BUF
2809+ DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n",
2810+ __func__, flush_domains, invalidate_domains);
2811+#endif
2812+ /*
2813+ * If we're invaliding the CPU cache and flushing a GPU cache,
2814+ * then pause for rendering so that the GPU caches will be
2815+ * flushed before the cpu cache is invalidated
2816+ */
2817+ if ((invalidate_domains & I915_GEM_DOMAIN_CPU) &&
2818+ (flush_domains & ~(I915_GEM_DOMAIN_CPU |
2819+ I915_GEM_DOMAIN_GTT))) {
2820+ ret = i915_gem_object_wait_rendering(obj);
2821+ if (ret)
2822+ return ret;
2823+ }
2824+ i915_gem_clflush_object(obj);
2825+ }
2826+
2827+ if ((write_domain | flush_domains) != 0)
2828+ obj->write_domain = write_domain;
2829+
2830+ /* If we're invalidating the CPU domain, clear the per-page CPU
2831+ * domain list as well.
2832+ */
2833+ if (obj_priv->page_cpu_valid != NULL &&
2834+ (obj->read_domains & I915_GEM_DOMAIN_CPU) &&
2835+ ((read_domains & I915_GEM_DOMAIN_CPU) == 0)) {
2836+ memset(obj_priv->page_cpu_valid, 0, obj->size / PAGE_SIZE);
2837+ }
2838+ obj->read_domains = read_domains;
2839+
2840+ dev->invalidate_domains |= invalidate_domains;
2841+ dev->flush_domains |= flush_domains;
2842+#if WATCH_BUF
2843+ DRM_INFO("%s: read %08x write %08x invalidate %08x flush %08x\n",
2844+ __func__,
2845+ obj->read_domains, obj->write_domain,
2846+ dev->invalidate_domains, dev->flush_domains);
2847+#endif
2848+ return 0;
2849+}
2850+
2851+/**
2852+ * Set the read/write domain on a range of the object.
2853+ *
2854+ * Currently only implemented for CPU reads, otherwise drops to normal
2855+ * i915_gem_object_set_domain().
2856+ */
2857+static int
2858+i915_gem_object_set_domain_range(struct drm_gem_object *obj,
2859+ uint64_t offset,
2860+ uint64_t size,
2861+ uint32_t read_domains,
2862+ uint32_t write_domain)
2863+{
2864+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2865+ int ret, i;
2866+
2867+ if (obj->read_domains & I915_GEM_DOMAIN_CPU)
2868+ return 0;
2869+
2870+ if (read_domains != I915_GEM_DOMAIN_CPU ||
2871+ write_domain != 0)
2872+ return i915_gem_object_set_domain(obj,
2873+ read_domains, write_domain);
2874+
2875+ /* Wait on any GPU rendering to the object to be flushed. */
2876+ if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) {
2877+ ret = i915_gem_object_wait_rendering(obj);
2878+ if (ret)
2879+ return ret;
2880+ }
2881+
2882+ if (obj_priv->page_cpu_valid == NULL) {
2883+ obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE,
2884+ DRM_MEM_DRIVER);
2885+ }
2886+
2887+ /* Flush the cache on any pages that are still invalid from the CPU's
2888+ * perspective.
2889+ */
2890+ for (i = offset / PAGE_SIZE; i < (offset + size - 1) / PAGE_SIZE; i++) {
2891+ if (obj_priv->page_cpu_valid[i])
2892+ continue;
2893+
2894+ drm_clflush_pages(obj_priv->page_list + i, 1);
2895+
2896+ obj_priv->page_cpu_valid[i] = 1;
2897+ }
2898+
2899+ return 0;
2900+}
2901+
2902+/**
2903+ * Once all of the objects have been set in the proper domain,
2904+ * perform the necessary flush and invalidate operations.
2905+ *
2906+ * Returns the write domains flushed, for use in flush tracking.
2907+ */
2908+static uint32_t
2909+i915_gem_dev_set_domain(struct drm_device *dev)
2910+{
2911+ uint32_t flush_domains = dev->flush_domains;
2912+
2913+ /*
2914+ * Now that all the buffers are synced to the proper domains,
2915+ * flush and invalidate the collected domains
2916+ */
2917+ if (dev->invalidate_domains | dev->flush_domains) {
2918+#if WATCH_EXEC
2919+ DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
2920+ __func__,
2921+ dev->invalidate_domains,
2922+ dev->flush_domains);
2923+#endif
2924+ i915_gem_flush(dev,
2925+ dev->invalidate_domains,
2926+ dev->flush_domains);
2927+ dev->invalidate_domains = 0;
2928+ dev->flush_domains = 0;
2929+ }
2930+
2931+ return flush_domains;
2932+}
2933+
2934+/**
2935+ * Pin an object to the GTT and evaluate the relocations landing in it.
2936+ */
2937+static int
2938+i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
2939+ struct drm_file *file_priv,
2940+ struct drm_i915_gem_exec_object *entry)
2941+{
2942+ struct drm_device *dev = obj->dev;
2943+ struct drm_i915_gem_relocation_entry reloc;
2944+ struct drm_i915_gem_relocation_entry __user *relocs;
2945+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2946+ int i, ret;
2947+ uint32_t last_reloc_offset = -1;
2948+ void *reloc_page = NULL;
2949+
2950+ /* Choose the GTT offset for our buffer and put it there. */
2951+ ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment);
2952+ if (ret)
2953+ return ret;
2954+
2955+ entry->offset = obj_priv->gtt_offset;
2956+
2957+ relocs = (struct drm_i915_gem_relocation_entry __user *)
2958+ (uintptr_t) entry->relocs_ptr;
2959+ /* Apply the relocations, using the GTT aperture to avoid cache
2960+ * flushing requirements.
2961+ */
2962+ for (i = 0; i < entry->relocation_count; i++) {
2963+ struct drm_gem_object *target_obj;
2964+ struct drm_i915_gem_object *target_obj_priv;
2965+ uint32_t reloc_val, reloc_offset, *reloc_entry;
2966+ int ret;
2967+
2968+ ret = copy_from_user(&reloc, relocs + i, sizeof(reloc));
2969+ if (ret != 0) {
2970+ i915_gem_object_unpin(obj);
2971+ return ret;
2972+ }
2973+
2974+ target_obj = drm_gem_object_lookup(obj->dev, file_priv,
2975+ reloc.target_handle);
2976+ if (target_obj == NULL) {
2977+ i915_gem_object_unpin(obj);
2978+ return -EBADF;
2979+ }
2980+ target_obj_priv = target_obj->driver_private;
2981+
2982+ /* The target buffer should have appeared before us in the
2983+ * exec_object list, so it should have a GTT space bound by now.
2984+ */
2985+ if (target_obj_priv->gtt_space == NULL) {
2986+ DRM_ERROR("No GTT space found for object %d\n",
2987+ reloc.target_handle);
2988+ drm_gem_object_unreference(target_obj);
2989+ i915_gem_object_unpin(obj);
2990+ return -EINVAL;
2991+ }
2992+
2993+ if (reloc.offset > obj->size - 4) {
2994+ DRM_ERROR("Relocation beyond object bounds: "
2995+ "obj %p target %d offset %d size %d.\n",
2996+ obj, reloc.target_handle,
2997+ (int) reloc.offset, (int) obj->size);
2998+ drm_gem_object_unreference(target_obj);
2999+ i915_gem_object_unpin(obj);
3000+ return -EINVAL;
3001+ }
3002+ if (reloc.offset & 3) {
3003+ DRM_ERROR("Relocation not 4-byte aligned: "
3004+ "obj %p target %d offset %d.\n",
3005+ obj, reloc.target_handle,
3006+ (int) reloc.offset);
3007+ drm_gem_object_unreference(target_obj);
3008+ i915_gem_object_unpin(obj);
3009+ return -EINVAL;
3010+ }
3011+
3012+ if (reloc.write_domain && target_obj->pending_write_domain &&
3013+ reloc.write_domain != target_obj->pending_write_domain) {
3014+ DRM_ERROR("Write domain conflict: "
3015+ "obj %p target %d offset %d "
3016+ "new %08x old %08x\n",
3017+ obj, reloc.target_handle,
3018+ (int) reloc.offset,
3019+ reloc.write_domain,
3020+ target_obj->pending_write_domain);
3021+ drm_gem_object_unreference(target_obj);
3022+ i915_gem_object_unpin(obj);
3023+ return -EINVAL;
3024+ }
3025+
3026+#if WATCH_RELOC
3027+ DRM_INFO("%s: obj %p offset %08x target %d "
3028+ "read %08x write %08x gtt %08x "
3029+ "presumed %08x delta %08x\n",
3030+ __func__,
3031+ obj,
3032+ (int) reloc.offset,
3033+ (int) reloc.target_handle,
3034+ (int) reloc.read_domains,
3035+ (int) reloc.write_domain,
3036+ (int) target_obj_priv->gtt_offset,
3037+ (int) reloc.presumed_offset,
3038+ reloc.delta);
3039+#endif
3040+
3041+ target_obj->pending_read_domains |= reloc.read_domains;
3042+ target_obj->pending_write_domain |= reloc.write_domain;
3043+
3044+ /* If the relocation already has the right value in it, no
3045+ * more work needs to be done.
3046+ */
3047+ if (target_obj_priv->gtt_offset == reloc.presumed_offset) {
3048+ drm_gem_object_unreference(target_obj);
3049+ continue;
3050+ }
3051+
3052+ /* Now that we're going to actually write some data in,
3053+ * make sure that any rendering using this buffer's contents
3054+ * is completed.
3055+ */
3056+ i915_gem_object_wait_rendering(obj);
3057+
3058+ /* As we're writing through the gtt, flush
3059+ * any CPU writes before we write the relocations
3060+ */
3061+ if (obj->write_domain & I915_GEM_DOMAIN_CPU) {
3062+ i915_gem_clflush_object(obj);
3063+ drm_agp_chipset_flush(dev);
3064+ obj->write_domain = 0;
3065+ }
3066+
3067+ /* Map the page containing the relocation we're going to
3068+ * perform.
3069+ */
3070+ reloc_offset = obj_priv->gtt_offset + reloc.offset;
3071+ if (reloc_page == NULL ||
3072+ (last_reloc_offset & ~(PAGE_SIZE - 1)) !=
3073+ (reloc_offset & ~(PAGE_SIZE - 1))) {
3074+ if (reloc_page != NULL)
3075+ iounmap(reloc_page);
3076+
3077+ reloc_page = ioremap(dev->agp->base +
3078+ (reloc_offset & ~(PAGE_SIZE - 1)),
3079+ PAGE_SIZE);
3080+ last_reloc_offset = reloc_offset;
3081+ if (reloc_page == NULL) {
3082+ drm_gem_object_unreference(target_obj);
3083+ i915_gem_object_unpin(obj);
3084+ return -ENOMEM;
3085+ }
3086+ }
3087+
3088+ reloc_entry = (uint32_t *)((char *)reloc_page +
3089+ (reloc_offset & (PAGE_SIZE - 1)));
3090+ reloc_val = target_obj_priv->gtt_offset + reloc.delta;
3091+
3092+#if WATCH_BUF
3093+ DRM_INFO("Applied relocation: %p@0x%08x %08x -> %08x\n",
3094+ obj, (unsigned int) reloc.offset,
3095+ readl(reloc_entry), reloc_val);
3096+#endif
3097+ writel(reloc_val, reloc_entry);
3098+
3099+ /* Write the updated presumed offset for this entry back out
3100+ * to the user.
3101+ */
3102+ reloc.presumed_offset = target_obj_priv->gtt_offset;
3103+ ret = copy_to_user(relocs + i, &reloc, sizeof(reloc));
3104+ if (ret != 0) {
3105+ drm_gem_object_unreference(target_obj);
3106+ i915_gem_object_unpin(obj);
3107+ return ret;
3108+ }
3109+
3110+ drm_gem_object_unreference(target_obj);
3111+ }
3112+
3113+ if (reloc_page != NULL)
3114+ iounmap(reloc_page);
3115+
3116+#if WATCH_BUF
3117+ if (0)
3118+ i915_gem_dump_object(obj, 128, __func__, ~0);
3119+#endif
3120+ return 0;
3121+}
3122+
3123+/** Dispatch a batchbuffer to the ring
3124+ */
3125+static int
3126+i915_dispatch_gem_execbuffer(struct drm_device *dev,
3127+ struct drm_i915_gem_execbuffer *exec,
3128+ uint64_t exec_offset)
3129+{
3130+ drm_i915_private_t *dev_priv = dev->dev_private;
3131+ struct drm_clip_rect __user *boxes = (struct drm_clip_rect __user *)
3132+ (uintptr_t) exec->cliprects_ptr;
3133+ int nbox = exec->num_cliprects;
3134+ int i = 0, count;
3135+ uint32_t exec_start, exec_len;
3136+ RING_LOCALS;
3137+
3138+ exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
3139+ exec_len = (uint32_t) exec->batch_len;
3140+
3141+ if ((exec_start | exec_len) & 0x7) {
3142+ DRM_ERROR("alignment\n");
3143+ return -EINVAL;
3144+ }
3145+
3146+ if (!exec_start)
3147+ return -EINVAL;
3148+
3149+ count = nbox ? nbox : 1;
3150+
3151+ for (i = 0; i < count; i++) {
3152+ if (i < nbox) {
3153+ int ret = i915_emit_box(dev, boxes, i,
3154+ exec->DR1, exec->DR4);
3155+ if (ret)
3156+ return ret;
3157+ }
3158+
3159+ if (IS_I830(dev) || IS_845G(dev)) {
3160+ BEGIN_LP_RING(4);
3161+ OUT_RING(MI_BATCH_BUFFER);
3162+ OUT_RING(exec_start | MI_BATCH_NON_SECURE);
3163+ OUT_RING(exec_start + exec_len - 4);
3164+ OUT_RING(0);
3165+ ADVANCE_LP_RING();
3166+ } else {
3167+ BEGIN_LP_RING(2);
3168+ if (IS_I965G(dev)) {
3169+ OUT_RING(MI_BATCH_BUFFER_START |
3170+ (2 << 6) |
3171+ MI_BATCH_NON_SECURE_I965);
3172+ OUT_RING(exec_start);
3173+ } else {
3174+ OUT_RING(MI_BATCH_BUFFER_START |
3175+ (2 << 6));
3176+ OUT_RING(exec_start | MI_BATCH_NON_SECURE);
3177+ }
3178+ ADVANCE_LP_RING();
3179+ }
3180+ }
3181+
3182+ /* XXX breadcrumb */
3183+ return 0;
3184+}
3185+
3186+/* Throttle our rendering by waiting until the ring has completed our requests
3187+ * emitted over 20 msec ago.
3188+ *
3189+ * This should get us reasonable parallelism between CPU and GPU but also
3190+ * relatively low latency when blocking on a particular request to finish.
3191+ */
3192+static int
3193+i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv)
3194+{
3195+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
3196+ int ret = 0;
3197+ uint32_t seqno;
3198+
3199+ mutex_lock(&dev->struct_mutex);
3200+ seqno = i915_file_priv->mm.last_gem_throttle_seqno;
3201+ i915_file_priv->mm.last_gem_throttle_seqno =
3202+ i915_file_priv->mm.last_gem_seqno;
3203+ if (seqno)
3204+ ret = i915_wait_request(dev, seqno);
3205+ mutex_unlock(&dev->struct_mutex);
3206+ return ret;
3207+}
3208+
3209+int
3210+i915_gem_execbuffer(struct drm_device *dev, void *data,
3211+ struct drm_file *file_priv)
3212+{
3213+ drm_i915_private_t *dev_priv = dev->dev_private;
3214+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
3215+ struct drm_i915_gem_execbuffer *args = data;
3216+ struct drm_i915_gem_exec_object *exec_list = NULL;
3217+ struct drm_gem_object **object_list = NULL;
3218+ struct drm_gem_object *batch_obj;
3219+ int ret, i, pinned = 0;
3220+ uint64_t exec_offset;
3221+ uint32_t seqno, flush_domains, pre_flush_domains;
3222+
3223+#if WATCH_EXEC
3224+ DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
3225+ (int) args->buffers_ptr, args->buffer_count, args->batch_len);
3226+#endif
3227+
3228+ /* Copy in the exec list from userland */
3229+ exec_list = drm_calloc(sizeof(*exec_list), args->buffer_count,
3230+ DRM_MEM_DRIVER);
3231+ object_list = drm_calloc(sizeof(*object_list), args->buffer_count,
3232+ DRM_MEM_DRIVER);
3233+ if (exec_list == NULL || object_list == NULL) {
3234+ DRM_ERROR("Failed to allocate exec or object list "
3235+ "for %d buffers\n",
3236+ args->buffer_count);
3237+ ret = -ENOMEM;
3238+ goto pre_mutex_err;
3239+ }
3240+ ret = copy_from_user(exec_list,
3241+ (struct drm_i915_relocation_entry __user *)
3242+ (uintptr_t) args->buffers_ptr,
3243+ sizeof(*exec_list) * args->buffer_count);
3244+ if (ret != 0) {
3245+ DRM_ERROR("copy %d exec entries failed %d\n",
3246+ args->buffer_count, ret);
3247+ goto pre_mutex_err;
3248+ }
3249+
3250+ mutex_lock(&dev->struct_mutex);
3251+
3252+ i915_verify_inactive(dev, __FILE__, __LINE__);
3253+
3254+ if (dev_priv->mm.wedged) {
3255+ DRM_ERROR("Execbuf while wedged\n");
3256+ mutex_unlock(&dev->struct_mutex);
3257+ return -EIO;
3258+ }
3259+
3260+ if (dev_priv->mm.suspended) {
3261+ DRM_ERROR("Execbuf while VT-switched.\n");
3262+ mutex_unlock(&dev->struct_mutex);
3263+ return -EBUSY;
3264+ }
3265+
3266+ /* Zero the gloabl flush/invalidate flags. These
3267+ * will be modified as each object is bound to the
3268+ * gtt
3269+ */
3270+ dev->invalidate_domains = 0;
3271+ dev->flush_domains = 0;
3272+
3273+ /* Look up object handles and perform the relocations */
3274+ for (i = 0; i < args->buffer_count; i++) {
3275+ object_list[i] = drm_gem_object_lookup(dev, file_priv,
3276+ exec_list[i].handle);
3277+ if (object_list[i] == NULL) {
3278+ DRM_ERROR("Invalid object handle %d at index %d\n",
3279+ exec_list[i].handle, i);
3280+ ret = -EBADF;
3281+ goto err;
3282+ }
3283+
3284+ object_list[i]->pending_read_domains = 0;
3285+ object_list[i]->pending_write_domain = 0;
3286+ ret = i915_gem_object_pin_and_relocate(object_list[i],
3287+ file_priv,
3288+ &exec_list[i]);
3289+ if (ret) {
3290+ DRM_ERROR("object bind and relocate failed %d\n", ret);
3291+ goto err;
3292+ }
3293+ pinned = i + 1;
3294+ }
3295+
3296+ /* Set the pending read domains for the batch buffer to COMMAND */
3297+ batch_obj = object_list[args->buffer_count-1];
3298+ batch_obj->pending_read_domains = I915_GEM_DOMAIN_COMMAND;
3299+ batch_obj->pending_write_domain = 0;
3300+
3301+ i915_verify_inactive(dev, __FILE__, __LINE__);
3302+
3303+ for (i = 0; i < args->buffer_count; i++) {
3304+ struct drm_gem_object *obj = object_list[i];
3305+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3306+
3307+ if (obj_priv->gtt_space == NULL) {
3308+ /* We evicted the buffer in the process of validating
3309+ * our set of buffers in. We could try to recover by
3310+ * kicking them everything out and trying again from
3311+ * the start.
3312+ */
3313+ ret = -ENOMEM;
3314+ goto err;
3315+ }
3316+
3317+ /* make sure all previous memory operations have passed */
3318+ ret = i915_gem_object_set_domain(obj,
3319+ obj->pending_read_domains,
3320+ obj->pending_write_domain);
3321+ if (ret)
3322+ goto err;
3323+ }
3324+
3325+ i915_verify_inactive(dev, __FILE__, __LINE__);
3326+
3327+ /* Flush/invalidate caches and chipset buffer */
3328+ flush_domains = i915_gem_dev_set_domain(dev);
3329+
3330+ i915_verify_inactive(dev, __FILE__, __LINE__);
3331+
3332+#if WATCH_COHERENCY
3333+ for (i = 0; i < args->buffer_count; i++) {
3334+ i915_gem_object_check_coherency(object_list[i],
3335+ exec_list[i].handle);
3336+ }
3337+#endif
3338+
3339+ exec_offset = exec_list[args->buffer_count - 1].offset;
3340+
3341+#if WATCH_EXEC
3342+ i915_gem_dump_object(object_list[args->buffer_count - 1],
3343+ args->batch_len,
3344+ __func__,
3345+ ~0);
3346+#endif
3347+
3348+ pre_flush_domains = flush_domains;
3349+
3350+ /* Exec the batchbuffer */
3351+ ret = i915_dispatch_gem_execbuffer(dev, args, exec_offset);
3352+ if (ret) {
3353+ DRM_ERROR("dispatch failed %d\n", ret);
3354+ goto err;
3355+ }
3356+
3357+ /*
3358+ * Ensure that the commands in the batch buffer are
3359+ * finished before the interrupt fires
3360+ */
3361+ flush_domains |= i915_retire_commands(dev);
3362+
3363+ i915_verify_inactive(dev, __FILE__, __LINE__);
3364+
3365+ /*
3366+ * Get a seqno representing the execution of the current buffer,
3367+ * which we can wait on. We would like to mitigate these interrupts,
3368+ * likely by only creating seqnos occasionally (so that we have
3369+ * *some* interrupts representing completion of buffers that we can
3370+ * wait on when trying to clear up gtt space).
3371+ */
3372+ seqno = i915_add_request(dev, flush_domains);
3373+ BUG_ON(seqno == 0);
3374+ i915_file_priv->mm.last_gem_seqno = seqno;
3375+ for (i = 0; i < args->buffer_count; i++) {
3376+ struct drm_gem_object *obj = object_list[i];
3377+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3378+
3379+ if (pre_flush_domains & obj->pending_write_domain &
3380+ ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) {
3381+ /* If we had a batchbuffer that resulted in a GPU
3382+ * domain being flushed before execution, followed by
3383+ * execution that resulted in the write_domain being
3384+ * set, then when that request is retired the
3385+ * write_domain would be incorrectly cleared. We're not
3386+ * sure that this can be triggered.
3387+ */
3388+ DRM_ERROR("Going to lose the write domain on "
3389+ "obj %d size %d\n",
3390+ exec_list[i].handle, obj->size);
3391+ }
3392+
3393+ i915_gem_object_move_to_active(obj);
3394+ obj_priv->last_rendering_seqno = seqno;
3395+#if WATCH_LRU
3396+ DRM_INFO("%s: move to exec list %p\n", __func__, obj);
3397+#endif
3398+ }
3399+#if WATCH_LRU
3400+ i915_dump_lru(dev, __func__);
3401+#endif
3402+
3403+ i915_verify_inactive(dev, __FILE__, __LINE__);
3404+
3405+ /* Copy the new buffer offsets back to the user's exec list. */
3406+ ret = copy_to_user((struct drm_i915_relocation_entry __user *)
3407+ (uintptr_t) args->buffers_ptr,
3408+ exec_list,
3409+ sizeof(*exec_list) * args->buffer_count);
3410+ if (ret)
3411+ DRM_ERROR("failed to copy %d exec entries "
3412+ "back to user (%d)\n",
3413+ args->buffer_count, ret);
3414+err:
3415+ if (object_list != NULL) {
3416+ for (i = 0; i < pinned; i++)
3417+ i915_gem_object_unpin(object_list[i]);
3418+
3419+ for (i = 0; i < args->buffer_count; i++)
3420+ drm_gem_object_unreference(object_list[i]);
3421+ }
3422+ mutex_unlock(&dev->struct_mutex);
3423+
3424+pre_mutex_err:
3425+ drm_free(object_list, sizeof(*object_list) * args->buffer_count,
3426+ DRM_MEM_DRIVER);
3427+ drm_free(exec_list, sizeof(*exec_list) * args->buffer_count,
3428+ DRM_MEM_DRIVER);
3429+
3430+ return ret;
3431+}
3432+
3433+int
3434+i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
3435+{
3436+ struct drm_device *dev = obj->dev;
3437+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3438+ int ret;
3439+
3440+ i915_verify_inactive(dev, __FILE__, __LINE__);
3441+ if (obj_priv->gtt_space == NULL) {
3442+ ret = i915_gem_object_bind_to_gtt(obj, alignment);
3443+ if (ret != 0) {
3444+ DRM_ERROR("Failure to bind: %d", ret);
3445+ return ret;
3446+ }
3447+ }
3448+ obj_priv->pin_count++;
3449+
3450+ /* If the object is not active and not pending a flush,
3451+ * remove it from the inactive list
3452+ */
3453+ if (obj_priv->pin_count == 1) {
3454+ atomic_inc(&dev->pin_count);
3455+ atomic_add(obj->size, &dev->pin_memory);
3456+ if (!obj_priv->active &&
3457+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
3458+ I915_GEM_DOMAIN_GTT)) == 0 &&
3459+ !list_empty(&obj_priv->list))
3460+ list_del_init(&obj_priv->list);
3461+ }
3462+ i915_verify_inactive(dev, __FILE__, __LINE__);
3463+
3464+ return 0;
3465+}
3466+
3467+void
3468+i915_gem_object_unpin(struct drm_gem_object *obj)
3469+{
3470+ struct drm_device *dev = obj->dev;
3471+ drm_i915_private_t *dev_priv = dev->dev_private;
3472+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3473+
3474+ i915_verify_inactive(dev, __FILE__, __LINE__);
3475+ obj_priv->pin_count--;
3476+ BUG_ON(obj_priv->pin_count < 0);
3477+ BUG_ON(obj_priv->gtt_space == NULL);
3478+
3479+ /* If the object is no longer pinned, and is
3480+ * neither active nor being flushed, then stick it on
3481+ * the inactive list
3482+ */
3483+ if (obj_priv->pin_count == 0) {
3484+ if (!obj_priv->active &&
3485+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
3486+ I915_GEM_DOMAIN_GTT)) == 0)
3487+ list_move_tail(&obj_priv->list,
3488+ &dev_priv->mm.inactive_list);
3489+ atomic_dec(&dev->pin_count);
3490+ atomic_sub(obj->size, &dev->pin_memory);
3491+ }
3492+ i915_verify_inactive(dev, __FILE__, __LINE__);
3493+}
3494+
3495+int
3496+i915_gem_pin_ioctl(struct drm_device *dev, void *data,
3497+ struct drm_file *file_priv)
3498+{
3499+ struct drm_i915_gem_pin *args = data;
3500+ struct drm_gem_object *obj;
3501+ struct drm_i915_gem_object *obj_priv;
3502+ int ret;
3503+
3504+ mutex_lock(&dev->struct_mutex);
3505+
3506+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3507+ if (obj == NULL) {
3508+ DRM_ERROR("Bad handle in i915_gem_pin_ioctl(): %d\n",
3509+ args->handle);
3510+ mutex_unlock(&dev->struct_mutex);
3511+ return -EBADF;
3512+ }
3513+ obj_priv = obj->driver_private;
3514+
3515+ ret = i915_gem_object_pin(obj, args->alignment);
3516+ if (ret != 0) {
3517+ drm_gem_object_unreference(obj);
3518+ mutex_unlock(&dev->struct_mutex);
3519+ return ret;
3520+ }
3521+
3522+ /* XXX - flush the CPU caches for pinned objects
3523+ * as the X server doesn't manage domains yet
3524+ */
3525+ if (obj->write_domain & I915_GEM_DOMAIN_CPU) {
3526+ i915_gem_clflush_object(obj);
3527+ drm_agp_chipset_flush(dev);
3528+ obj->write_domain = 0;
3529+ }
3530+ args->offset = obj_priv->gtt_offset;
3531+ drm_gem_object_unreference(obj);
3532+ mutex_unlock(&dev->struct_mutex);
3533+
3534+ return 0;
3535+}
3536+
3537+int
3538+i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
3539+ struct drm_file *file_priv)
3540+{
3541+ struct drm_i915_gem_pin *args = data;
3542+ struct drm_gem_object *obj;
3543+
3544+ mutex_lock(&dev->struct_mutex);
3545+
3546+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3547+ if (obj == NULL) {
3548+ DRM_ERROR("Bad handle in i915_gem_unpin_ioctl(): %d\n",
3549+ args->handle);
3550+ mutex_unlock(&dev->struct_mutex);
3551+ return -EBADF;
3552+ }
3553+
3554+ i915_gem_object_unpin(obj);
3555+
3556+ drm_gem_object_unreference(obj);
3557+ mutex_unlock(&dev->struct_mutex);
3558+ return 0;
3559+}
3560+
3561+int
3562+i915_gem_busy_ioctl(struct drm_device *dev, void *data,
3563+ struct drm_file *file_priv)
3564+{
3565+ struct drm_i915_gem_busy *args = data;
3566+ struct drm_gem_object *obj;
3567+ struct drm_i915_gem_object *obj_priv;
3568+
3569+ mutex_lock(&dev->struct_mutex);
3570+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3571+ if (obj == NULL) {
3572+ DRM_ERROR("Bad handle in i915_gem_busy_ioctl(): %d\n",
3573+ args->handle);
3574+ mutex_unlock(&dev->struct_mutex);
3575+ return -EBADF;
3576+ }
3577+
3578+ obj_priv = obj->driver_private;
3579+ args->busy = obj_priv->active;
3580+
3581+ drm_gem_object_unreference(obj);
3582+ mutex_unlock(&dev->struct_mutex);
3583+ return 0;
3584+}
3585+
3586+int
3587+i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
3588+ struct drm_file *file_priv)
3589+{
3590+ return i915_gem_ring_throttle(dev, file_priv);
3591+}
3592+
3593+int i915_gem_init_object(struct drm_gem_object *obj)
3594+{
3595+ struct drm_i915_gem_object *obj_priv;
3596+
3597+ obj_priv = drm_calloc(1, sizeof(*obj_priv), DRM_MEM_DRIVER);
3598+ if (obj_priv == NULL)
3599+ return -ENOMEM;
3600+
3601+ /*
3602+ * We've just allocated pages from the kernel,
3603+ * so they've just been written by the CPU with
3604+ * zeros. They'll need to be clflushed before we
3605+ * use them with the GPU.
3606+ */
3607+ obj->write_domain = I915_GEM_DOMAIN_CPU;
3608+ obj->read_domains = I915_GEM_DOMAIN_CPU;
3609+
3610+ obj->driver_private = obj_priv;
3611+ obj_priv->obj = obj;
3612+ INIT_LIST_HEAD(&obj_priv->list);
3613+ return 0;
3614+}
3615+
3616+void i915_gem_free_object(struct drm_gem_object *obj)
3617+{
3618+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3619+
3620+ while (obj_priv->pin_count > 0)
3621+ i915_gem_object_unpin(obj);
3622+
3623+ i915_gem_object_unbind(obj);
3624+
3625+ drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER);
3626+ drm_free(obj->driver_private, 1, DRM_MEM_DRIVER);
3627+}
3628+
3629+static int
3630+i915_gem_set_domain(struct drm_gem_object *obj,
3631+ struct drm_file *file_priv,
3632+ uint32_t read_domains,
3633+ uint32_t write_domain)
3634+{
3635+ struct drm_device *dev = obj->dev;
3636+ int ret;
3637+ uint32_t flush_domains;
3638+
3639+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
3640+
3641+ ret = i915_gem_object_set_domain(obj, read_domains, write_domain);
3642+ if (ret)
3643+ return ret;
3644+ flush_domains = i915_gem_dev_set_domain(obj->dev);
3645+
3646+ if (flush_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT))
3647+ (void) i915_add_request(dev, flush_domains);
3648+
3649+ return 0;
3650+}
3651+
3652+/** Unbinds all objects that are on the given buffer list. */
3653+static int
3654+i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head)
3655+{
3656+ struct drm_gem_object *obj;
3657+ struct drm_i915_gem_object *obj_priv;
3658+ int ret;
3659+
3660+ while (!list_empty(head)) {
3661+ obj_priv = list_first_entry(head,
3662+ struct drm_i915_gem_object,
3663+ list);
3664+ obj = obj_priv->obj;
3665+
3666+ if (obj_priv->pin_count != 0) {
3667+ DRM_ERROR("Pinned object in unbind list\n");
3668+ mutex_unlock(&dev->struct_mutex);
3669+ return -EINVAL;
3670+ }
3671+
3672+ ret = i915_gem_object_unbind(obj);
3673+ if (ret != 0) {
3674+ DRM_ERROR("Error unbinding object in LeaveVT: %d\n",
3675+ ret);
3676+ mutex_unlock(&dev->struct_mutex);
3677+ return ret;
3678+ }
3679+ }
3680+
3681+
3682+ return 0;
3683+}
3684+
3685+static int
3686+i915_gem_idle(struct drm_device *dev)
3687+{
3688+ drm_i915_private_t *dev_priv = dev->dev_private;
3689+ uint32_t seqno, cur_seqno, last_seqno;
3690+ int stuck;
3691+
3692+ if (dev_priv->mm.suspended)
3693+ return 0;
3694+
3695+ /* Hack! Don't let anybody do execbuf while we don't control the chip.
3696+ * We need to replace this with a semaphore, or something.
3697+ */
3698+ dev_priv->mm.suspended = 1;
3699+
3700+ i915_kernel_lost_context(dev);
3701+
3702+ /* Flush the GPU along with all non-CPU write domains
3703+ */
3704+ i915_gem_flush(dev, ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT),
3705+ ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
3706+ seqno = i915_add_request(dev, ~(I915_GEM_DOMAIN_CPU |
3707+ I915_GEM_DOMAIN_GTT));
3708+
3709+ if (seqno == 0) {
3710+ mutex_unlock(&dev->struct_mutex);
3711+ return -ENOMEM;
3712+ }
3713+
3714+ dev_priv->mm.waiting_gem_seqno = seqno;
3715+ last_seqno = 0;
3716+ stuck = 0;
3717+ for (;;) {
3718+ cur_seqno = i915_get_gem_seqno(dev);
3719+ if (i915_seqno_passed(cur_seqno, seqno))
3720+ break;
3721+ if (last_seqno == cur_seqno) {
3722+ if (stuck++ > 100) {
3723+ DRM_ERROR("hardware wedged\n");
3724+ dev_priv->mm.wedged = 1;
3725+ DRM_WAKEUP(&dev_priv->irq_queue);
3726+ break;
3727+ }
3728+ }
3729+ msleep(10);
3730+ last_seqno = cur_seqno;
3731+ }
3732+ dev_priv->mm.waiting_gem_seqno = 0;
3733+
3734+ i915_gem_retire_requests(dev);
3735+
3736+ /* Active and flushing should now be empty as we've
3737+ * waited for a sequence higher than any pending execbuffer
3738+ */
3739+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3740+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3741+
3742+ /* Request should now be empty as we've also waited
3743+ * for the last request in the list
3744+ */
3745+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3746+
3747+ /* Move all buffers out of the GTT. */
3748+ i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list);
3749+
3750+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3751+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3752+ BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
3753+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3754+ return 0;
3755+}
3756+
3757+static int
3758+i915_gem_init_hws(struct drm_device *dev)
3759+{
3760+ drm_i915_private_t *dev_priv = dev->dev_private;
3761+ struct drm_gem_object *obj;
3762+ struct drm_i915_gem_object *obj_priv;
3763+ int ret;
3764+
3765+ /* If we need a physical address for the status page, it's already
3766+ * initialized at driver load time.
3767+ */
3768+ if (!I915_NEED_GFX_HWS(dev))
3769+ return 0;
3770+
3771+ obj = drm_gem_object_alloc(dev, 4096);
3772+ if (obj == NULL) {
3773+ DRM_ERROR("Failed to allocate status page\n");
3774+ return -ENOMEM;
3775+ }
3776+ obj_priv = obj->driver_private;
3777+
3778+ ret = i915_gem_object_pin(obj, 4096);
3779+ if (ret != 0) {
3780+ drm_gem_object_unreference(obj);
3781+ return ret;
3782+ }
3783+
3784+ dev_priv->status_gfx_addr = obj_priv->gtt_offset;
3785+ dev_priv->hws_map.offset = dev->agp->base + obj_priv->gtt_offset;
3786+ dev_priv->hws_map.size = 4096;
3787+ dev_priv->hws_map.type = 0;
3788+ dev_priv->hws_map.flags = 0;
3789+ dev_priv->hws_map.mtrr = 0;
3790+
3791+ drm_core_ioremap(&dev_priv->hws_map, dev);
3792+ if (dev_priv->hws_map.handle == NULL) {
3793+ DRM_ERROR("Failed to map status page.\n");
3794+ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3795+ drm_gem_object_unreference(obj);
3796+ return -EINVAL;
3797+ }
3798+ dev_priv->hws_obj = obj;
3799+ dev_priv->hw_status_page = dev_priv->hws_map.handle;
3800+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
3801+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
3802+ DRM_DEBUG("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
3803+
3804+ return 0;
3805+}
3806+
3807+static int
3808+i915_gem_init_ringbuffer(struct drm_device *dev)
3809+{
3810+ drm_i915_private_t *dev_priv = dev->dev_private;
3811+ struct drm_gem_object *obj;
3812+ struct drm_i915_gem_object *obj_priv;
3813+ int ret;
3814+
3815+ ret = i915_gem_init_hws(dev);
3816+ if (ret != 0)
3817+ return ret;
3818+
3819+ obj = drm_gem_object_alloc(dev, 128 * 1024);
3820+ if (obj == NULL) {
3821+ DRM_ERROR("Failed to allocate ringbuffer\n");
3822+ return -ENOMEM;
3823+ }
3824+ obj_priv = obj->driver_private;
3825+
3826+ ret = i915_gem_object_pin(obj, 4096);
3827+ if (ret != 0) {
3828+ drm_gem_object_unreference(obj);
3829+ return ret;
3830+ }
3831+
3832+ /* Set up the kernel mapping for the ring. */
3833+ dev_priv->ring.Size = obj->size;
3834+ dev_priv->ring.tail_mask = obj->size - 1;
3835+
3836+ dev_priv->ring.map.offset = dev->agp->base + obj_priv->gtt_offset;
3837+ dev_priv->ring.map.size = obj->size;
3838+ dev_priv->ring.map.type = 0;
3839+ dev_priv->ring.map.flags = 0;
3840+ dev_priv->ring.map.mtrr = 0;
3841+
3842+ drm_core_ioremap(&dev_priv->ring.map, dev);
3843+ if (dev_priv->ring.map.handle == NULL) {
3844+ DRM_ERROR("Failed to map ringbuffer.\n");
3845+ memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3846+ drm_gem_object_unreference(obj);
3847+ return -EINVAL;
3848+ }
3849+ dev_priv->ring.ring_obj = obj;
3850+ dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
3851+
3852+ /* Stop the ring if it's running. */
3853+ I915_WRITE(PRB0_CTL, 0);
3854+ I915_WRITE(PRB0_HEAD, 0);
3855+ I915_WRITE(PRB0_TAIL, 0);
3856+ I915_WRITE(PRB0_START, 0);
3857+
3858+ /* Initialize the ring. */
3859+ I915_WRITE(PRB0_START, obj_priv->gtt_offset);
3860+ I915_WRITE(PRB0_CTL,
3861+ ((obj->size - 4096) & RING_NR_PAGES) |
3862+ RING_NO_REPORT |
3863+ RING_VALID);
3864+
3865+ /* Update our cache of the ring state */
3866+ i915_kernel_lost_context(dev);
3867+
3868+ return 0;
3869+}
3870+
3871+static void
3872+i915_gem_cleanup_ringbuffer(struct drm_device *dev)
3873+{
3874+ drm_i915_private_t *dev_priv = dev->dev_private;
3875+
3876+ if (dev_priv->ring.ring_obj == NULL)
3877+ return;
3878+
3879+ drm_core_ioremapfree(&dev_priv->ring.map, dev);
3880+
3881+ i915_gem_object_unpin(dev_priv->ring.ring_obj);
3882+ drm_gem_object_unreference(dev_priv->ring.ring_obj);
3883+ dev_priv->ring.ring_obj = NULL;
3884+ memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3885+
3886+ if (dev_priv->hws_obj != NULL) {
3887+ i915_gem_object_unpin(dev_priv->hws_obj);
3888+ drm_gem_object_unreference(dev_priv->hws_obj);
3889+ dev_priv->hws_obj = NULL;
3890+ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3891+
3892+ /* Write high address into HWS_PGA when disabling. */
3893+ I915_WRITE(HWS_PGA, 0x1ffff000);
3894+ }
3895+}
3896+
3897+int
3898+i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
3899+ struct drm_file *file_priv)
3900+{
3901+ drm_i915_private_t *dev_priv = dev->dev_private;
3902+ int ret;
3903+
3904+ if (dev_priv->mm.wedged) {
3905+ DRM_ERROR("Reenabling wedged hardware, good luck\n");
3906+ dev_priv->mm.wedged = 0;
3907+ }
3908+
3909+ ret = i915_gem_init_ringbuffer(dev);
3910+ if (ret != 0)
3911+ return ret;
3912+
3913+ mutex_lock(&dev->struct_mutex);
3914+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3915+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3916+ BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
3917+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3918+ dev_priv->mm.suspended = 0;
3919+ mutex_unlock(&dev->struct_mutex);
3920+ return 0;
3921+}
3922+
3923+int
3924+i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
3925+ struct drm_file *file_priv)
3926+{
3927+ int ret;
3928+
3929+ mutex_lock(&dev->struct_mutex);
3930+ ret = i915_gem_idle(dev);
3931+ if (ret == 0)
3932+ i915_gem_cleanup_ringbuffer(dev);
3933+ mutex_unlock(&dev->struct_mutex);
3934+
3935+ return 0;
3936+}
3937+
3938+void
3939+i915_gem_lastclose(struct drm_device *dev)
3940+{
3941+ int ret;
3942+ drm_i915_private_t *dev_priv = dev->dev_private;
3943+
3944+ mutex_lock(&dev->struct_mutex);
3945+
3946+ if (dev_priv->ring.ring_obj != NULL) {
3947+ ret = i915_gem_idle(dev);
3948+ if (ret)
3949+ DRM_ERROR("failed to idle hardware: %d\n", ret);
3950+
3951+ i915_gem_cleanup_ringbuffer(dev);
3952+ }
3953+
3954+ mutex_unlock(&dev->struct_mutex);
3955+}
3956+
3957+void
3958+i915_gem_load(struct drm_device *dev)
3959+{
3960+ drm_i915_private_t *dev_priv = dev->dev_private;
3961+
3962+ INIT_LIST_HEAD(&dev_priv->mm.active_list);
3963+ INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
3964+ INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
3965+ INIT_LIST_HEAD(&dev_priv->mm.request_list);
3966+ INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
3967+ i915_gem_retire_work_handler);
3968+ dev_priv->mm.next_gem_seqno = 1;
3969+
3970+ i915_gem_detect_bit_6_swizzle(dev);
3971+}
3972--- /dev/null
3973+++ b/drivers/gpu/drm/i915/i915_gem_debug.c
3974@@ -0,0 +1,201 @@
3975+/*
3976+ * Copyright © 2008 Intel Corporation
3977+ *
3978+ * Permission is hereby granted, free of charge, to any person obtaining a
3979+ * copy of this software and associated documentation files (the "Software"),
3980+ * to deal in the Software without restriction, including without limitation
3981+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
3982+ * and/or sell copies of the Software, and to permit persons to whom the
3983+ * Software is furnished to do so, subject to the following conditions:
3984+ *
3985+ * The above copyright notice and this permission notice (including the next
3986+ * paragraph) shall be included in all copies or substantial portions of the
3987+ * Software.
3988+ *
3989+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3990+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3991+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
3992+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3993+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
3994+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
3995+ * IN THE SOFTWARE.
3996+ *
3997+ * Authors:
3998+ * Keith Packard <keithp@keithp.com>
3999+ *
4000+ */
4001+
4002+#include "drmP.h"
4003+#include "drm.h"
4004+#include "i915_drm.h"
4005+#include "i915_drv.h"
4006+
4007+#if WATCH_INACTIVE
4008+void
4009+i915_verify_inactive(struct drm_device *dev, char *file, int line)
4010+{
4011+ drm_i915_private_t *dev_priv = dev->dev_private;
4012+ struct drm_gem_object *obj;
4013+ struct drm_i915_gem_object *obj_priv;
4014+
4015+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
4016+ obj = obj_priv->obj;
4017+ if (obj_priv->pin_count || obj_priv->active ||
4018+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
4019+ I915_GEM_DOMAIN_GTT)))
4020+ DRM_ERROR("inactive %p (p %d a %d w %x) %s:%d\n",
4021+ obj,
4022+ obj_priv->pin_count, obj_priv->active,
4023+ obj->write_domain, file, line);
4024+ }
4025+}
4026+#endif /* WATCH_INACTIVE */
4027+
4028+
4029+#if WATCH_BUF | WATCH_EXEC | WATCH_PWRITE
4030+static void
4031+i915_gem_dump_page(struct page *page, uint32_t start, uint32_t end,
4032+ uint32_t bias, uint32_t mark)
4033+{
4034+ uint32_t *mem = kmap_atomic(page, KM_USER0);
4035+ int i;
4036+ for (i = start; i < end; i += 4)
4037+ DRM_INFO("%08x: %08x%s\n",
4038+ (int) (bias + i), mem[i / 4],
4039+ (bias + i == mark) ? " ********" : "");
4040+ kunmap_atomic(mem, KM_USER0);
4041+ /* give syslog time to catch up */
4042+ msleep(1);
4043+}
4044+
4045+void
4046+i915_gem_dump_object(struct drm_gem_object *obj, int len,
4047+ const char *where, uint32_t mark)
4048+{
4049+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
4050+ int page;
4051+
4052+ DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset);
4053+ for (page = 0; page < (len + PAGE_SIZE-1) / PAGE_SIZE; page++) {
4054+ int page_len, chunk, chunk_len;
4055+
4056+ page_len = len - page * PAGE_SIZE;
4057+ if (page_len > PAGE_SIZE)
4058+ page_len = PAGE_SIZE;
4059+
4060+ for (chunk = 0; chunk < page_len; chunk += 128) {
4061+ chunk_len = page_len - chunk;
4062+ if (chunk_len > 128)
4063+ chunk_len = 128;
4064+ i915_gem_dump_page(obj_priv->page_list[page],
4065+ chunk, chunk + chunk_len,
4066+ obj_priv->gtt_offset +
4067+ page * PAGE_SIZE,
4068+ mark);
4069+ }
4070+ }
4071+}
4072+#endif
4073+
4074+#if WATCH_LRU
4075+void
4076+i915_dump_lru(struct drm_device *dev, const char *where)
4077+{
4078+ drm_i915_private_t *dev_priv = dev->dev_private;
4079+ struct drm_i915_gem_object *obj_priv;
4080+
4081+ DRM_INFO("active list %s {\n", where);
4082+ list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
4083+ list)
4084+ {
4085+ DRM_INFO(" %p: %08x\n", obj_priv,
4086+ obj_priv->last_rendering_seqno);
4087+ }
4088+ DRM_INFO("}\n");
4089+ DRM_INFO("flushing list %s {\n", where);
4090+ list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
4091+ list)
4092+ {
4093+ DRM_INFO(" %p: %08x\n", obj_priv,
4094+ obj_priv->last_rendering_seqno);
4095+ }
4096+ DRM_INFO("}\n");
4097+ DRM_INFO("inactive %s {\n", where);
4098+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
4099+ DRM_INFO(" %p: %08x\n", obj_priv,
4100+ obj_priv->last_rendering_seqno);
4101+ }
4102+ DRM_INFO("}\n");
4103+}
4104+#endif
4105+
4106+
4107+#if WATCH_COHERENCY
4108+void
4109+i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle)
4110+{
4111+ struct drm_device *dev = obj->dev;
4112+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
4113+ int page;
4114+ uint32_t *gtt_mapping;
4115+ uint32_t *backing_map = NULL;
4116+ int bad_count = 0;
4117+
4118+ DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %dkb):\n",
4119+ __func__, obj, obj_priv->gtt_offset, handle,
4120+ obj->size / 1024);
4121+
4122+ gtt_mapping = ioremap(dev->agp->base + obj_priv->gtt_offset,
4123+ obj->size);
4124+ if (gtt_mapping == NULL) {
4125+ DRM_ERROR("failed to map GTT space\n");
4126+ return;
4127+ }
4128+
4129+ for (page = 0; page < obj->size / PAGE_SIZE; page++) {
4130+ int i;
4131+
4132+ backing_map = kmap_atomic(obj_priv->page_list[page], KM_USER0);
4133+
4134+ if (backing_map == NULL) {
4135+ DRM_ERROR("failed to map backing page\n");
4136+ goto out;
4137+ }
4138+
4139+ for (i = 0; i < PAGE_SIZE / 4; i++) {
4140+ uint32_t cpuval = backing_map[i];
4141+ uint32_t gttval = readl(gtt_mapping +
4142+ page * 1024 + i);
4143+
4144+ if (cpuval != gttval) {
4145+ DRM_INFO("incoherent CPU vs GPU at 0x%08x: "
4146+ "0x%08x vs 0x%08x\n",
4147+ (int)(obj_priv->gtt_offset +
4148+ page * PAGE_SIZE + i * 4),
4149+ cpuval, gttval);
4150+ if (bad_count++ >= 8) {
4151+ DRM_INFO("...\n");
4152+ goto out;
4153+ }
4154+ }
4155+ }
4156+ kunmap_atomic(backing_map, KM_USER0);
4157+ backing_map = NULL;
4158+ }
4159+
4160+ out:
4161+ if (backing_map != NULL)
4162+ kunmap_atomic(backing_map, KM_USER0);
4163+ iounmap(gtt_mapping);
4164+
4165+ /* give syslog time to catch up */
4166+ msleep(1);
4167+
4168+ /* Directly flush the object, since we just loaded values with the CPU
4169+ * from the backing pages and we don't want to disturb the cache
4170+ * management that we're trying to observe.
4171+ */
4172+
4173+ i915_gem_clflush_object(obj);
4174+}
4175+#endif
4176--- /dev/null
4177+++ b/drivers/gpu/drm/i915/i915_gem_proc.c
4178@@ -0,0 +1,292 @@
4179+/*
4180+ * Copyright © 2008 Intel Corporation
4181+ *
4182+ * Permission is hereby granted, free of charge, to any person obtaining a
4183+ * copy of this software and associated documentation files (the "Software"),
4184+ * to deal in the Software without restriction, including without limitation
4185+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4186+ * and/or sell copies of the Software, and to permit persons to whom the
4187+ * Software is furnished to do so, subject to the following conditions:
4188+ *
4189+ * The above copyright notice and this permission notice (including the next
4190+ * paragraph) shall be included in all copies or substantial portions of the
4191+ * Software.
4192+ *
4193+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4194+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4195+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4196+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4197+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4198+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
4199+ * IN THE SOFTWARE.
4200+ *
4201+ * Authors:
4202+ * Eric Anholt <eric@anholt.net>
4203+ * Keith Packard <keithp@keithp.com>
4204+ *
4205+ */
4206+
4207+#include "drmP.h"
4208+#include "drm.h"
4209+#include "i915_drm.h"
4210+#include "i915_drv.h"
4211+
4212+static int i915_gem_active_info(char *buf, char **start, off_t offset,
4213+ int request, int *eof, void *data)
4214+{
4215+ struct drm_minor *minor = (struct drm_minor *) data;
4216+ struct drm_device *dev = minor->dev;
4217+ drm_i915_private_t *dev_priv = dev->dev_private;
4218+ struct drm_i915_gem_object *obj_priv;
4219+ int len = 0;
4220+
4221+ if (offset > DRM_PROC_LIMIT) {
4222+ *eof = 1;
4223+ return 0;
4224+ }
4225+
4226+ *start = &buf[offset];
4227+ *eof = 0;
4228+ DRM_PROC_PRINT("Active:\n");
4229+ list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
4230+ list)
4231+ {
4232+ struct drm_gem_object *obj = obj_priv->obj;
4233+ if (obj->name) {
4234+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4235+ obj, obj->name,
4236+ obj->read_domains, obj->write_domain,
4237+ obj_priv->last_rendering_seqno);
4238+ } else {
4239+ DRM_PROC_PRINT(" %p: %08x %08x %d\n",
4240+ obj,
4241+ obj->read_domains, obj->write_domain,
4242+ obj_priv->last_rendering_seqno);
4243+ }
4244+ }
4245+ if (len > request + offset)
4246+ return request;
4247+ *eof = 1;
4248+ return len - offset;
4249+}
4250+
4251+static int i915_gem_flushing_info(char *buf, char **start, off_t offset,
4252+ int request, int *eof, void *data)
4253+{
4254+ struct drm_minor *minor = (struct drm_minor *) data;
4255+ struct drm_device *dev = minor->dev;
4256+ drm_i915_private_t *dev_priv = dev->dev_private;
4257+ struct drm_i915_gem_object *obj_priv;
4258+ int len = 0;
4259+
4260+ if (offset > DRM_PROC_LIMIT) {
4261+ *eof = 1;
4262+ return 0;
4263+ }
4264+
4265+ *start = &buf[offset];
4266+ *eof = 0;
4267+ DRM_PROC_PRINT("Flushing:\n");
4268+ list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
4269+ list)
4270+ {
4271+ struct drm_gem_object *obj = obj_priv->obj;
4272+ if (obj->name) {
4273+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4274+ obj, obj->name,
4275+ obj->read_domains, obj->write_domain,
4276+ obj_priv->last_rendering_seqno);
4277+ } else {
4278+ DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
4279+ obj->read_domains, obj->write_domain,
4280+ obj_priv->last_rendering_seqno);
4281+ }
4282+ }
4283+ if (len > request + offset)
4284+ return request;
4285+ *eof = 1;
4286+ return len - offset;
4287+}
4288+
4289+static int i915_gem_inactive_info(char *buf, char **start, off_t offset,
4290+ int request, int *eof, void *data)
4291+{
4292+ struct drm_minor *minor = (struct drm_minor *) data;
4293+ struct drm_device *dev = minor->dev;
4294+ drm_i915_private_t *dev_priv = dev->dev_private;
4295+ struct drm_i915_gem_object *obj_priv;
4296+ int len = 0;
4297+
4298+ if (offset > DRM_PROC_LIMIT) {
4299+ *eof = 1;
4300+ return 0;
4301+ }
4302+
4303+ *start = &buf[offset];
4304+ *eof = 0;
4305+ DRM_PROC_PRINT("Inactive:\n");
4306+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list,
4307+ list)
4308+ {
4309+ struct drm_gem_object *obj = obj_priv->obj;
4310+ if (obj->name) {
4311+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4312+ obj, obj->name,
4313+ obj->read_domains, obj->write_domain,
4314+ obj_priv->last_rendering_seqno);
4315+ } else {
4316+ DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
4317+ obj->read_domains, obj->write_domain,
4318+ obj_priv->last_rendering_seqno);
4319+ }
4320+ }
4321+ if (len > request + offset)
4322+ return request;
4323+ *eof = 1;
4324+ return len - offset;
4325+}
4326+
4327+static int i915_gem_request_info(char *buf, char **start, off_t offset,
4328+ int request, int *eof, void *data)
4329+{
4330+ struct drm_minor *minor = (struct drm_minor *) data;
4331+ struct drm_device *dev = minor->dev;
4332+ drm_i915_private_t *dev_priv = dev->dev_private;
4333+ struct drm_i915_gem_request *gem_request;
4334+ int len = 0;
4335+
4336+ if (offset > DRM_PROC_LIMIT) {
4337+ *eof = 1;
4338+ return 0;
4339+ }
4340+
4341+ *start = &buf[offset];
4342+ *eof = 0;
4343+ DRM_PROC_PRINT("Request:\n");
4344+ list_for_each_entry(gem_request, &dev_priv->mm.request_list,
4345+ list)
4346+ {
4347+ DRM_PROC_PRINT(" %d @ %d %08x\n",
4348+ gem_request->seqno,
4349+ (int) (jiffies - gem_request->emitted_jiffies),
4350+ gem_request->flush_domains);
4351+ }
4352+ if (len > request + offset)
4353+ return request;
4354+ *eof = 1;
4355+ return len - offset;
4356+}
4357+
4358+static int i915_gem_seqno_info(char *buf, char **start, off_t offset,
4359+ int request, int *eof, void *data)
4360+{
4361+ struct drm_minor *minor = (struct drm_minor *) data;
4362+ struct drm_device *dev = minor->dev;
4363+ drm_i915_private_t *dev_priv = dev->dev_private;
4364+ int len = 0;
4365+
4366+ if (offset > DRM_PROC_LIMIT) {
4367+ *eof = 1;
4368+ return 0;
4369+ }
4370+
4371+ *start = &buf[offset];
4372+ *eof = 0;
4373+ DRM_PROC_PRINT("Current sequence: %d\n", i915_get_gem_seqno(dev));
4374+ DRM_PROC_PRINT("Waiter sequence: %d\n",
4375+ dev_priv->mm.waiting_gem_seqno);
4376+ DRM_PROC_PRINT("IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno);
4377+ if (len > request + offset)
4378+ return request;
4379+ *eof = 1;
4380+ return len - offset;
4381+}
4382+
4383+
4384+static int i915_interrupt_info(char *buf, char **start, off_t offset,
4385+ int request, int *eof, void *data)
4386+{
4387+ struct drm_minor *minor = (struct drm_minor *) data;
4388+ struct drm_device *dev = minor->dev;
4389+ drm_i915_private_t *dev_priv = dev->dev_private;
4390+ int len = 0;
4391+
4392+ if (offset > DRM_PROC_LIMIT) {
4393+ *eof = 1;
4394+ return 0;
4395+ }
4396+
4397+ *start = &buf[offset];
4398+ *eof = 0;
4399+ DRM_PROC_PRINT("Interrupt enable: %08x\n",
4400+ I915_READ(IER));
4401+ DRM_PROC_PRINT("Interrupt identity: %08x\n",
4402+ I915_READ(IIR));
4403+ DRM_PROC_PRINT("Interrupt mask: %08x\n",
4404+ I915_READ(IMR));
4405+ DRM_PROC_PRINT("Pipe A stat: %08x\n",
4406+ I915_READ(PIPEASTAT));
4407+ DRM_PROC_PRINT("Pipe B stat: %08x\n",
4408+ I915_READ(PIPEBSTAT));
4409+ DRM_PROC_PRINT("Interrupts received: %d\n",
4410+ atomic_read(&dev_priv->irq_received));
4411+ DRM_PROC_PRINT("Current sequence: %d\n",
4412+ i915_get_gem_seqno(dev));
4413+ DRM_PROC_PRINT("Waiter sequence: %d\n",
4414+ dev_priv->mm.waiting_gem_seqno);
4415+ DRM_PROC_PRINT("IRQ sequence: %d\n",
4416+ dev_priv->mm.irq_gem_seqno);
4417+ if (len > request + offset)
4418+ return request;
4419+ *eof = 1;
4420+ return len - offset;
4421+}
4422+
4423+static struct drm_proc_list {
4424+ /** file name */
4425+ const char *name;
4426+ /** proc callback*/
4427+ int (*f) (char *, char **, off_t, int, int *, void *);
4428+} i915_gem_proc_list[] = {
4429+ {"i915_gem_active", i915_gem_active_info},
4430+ {"i915_gem_flushing", i915_gem_flushing_info},
4431+ {"i915_gem_inactive", i915_gem_inactive_info},
4432+ {"i915_gem_request", i915_gem_request_info},
4433+ {"i915_gem_seqno", i915_gem_seqno_info},
4434+ {"i915_gem_interrupt", i915_interrupt_info},
4435+};
4436+
4437+#define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list)
4438+
4439+int i915_gem_proc_init(struct drm_minor *minor)
4440+{
4441+ struct proc_dir_entry *ent;
4442+ int i, j;
4443+
4444+ for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) {
4445+ ent = create_proc_entry(i915_gem_proc_list[i].name,
4446+ S_IFREG | S_IRUGO, minor->dev_root);
4447+ if (!ent) {
4448+ DRM_ERROR("Cannot create /proc/dri/.../%s\n",
4449+ i915_gem_proc_list[i].name);
4450+ for (j = 0; j < i; j++)
4451+ remove_proc_entry(i915_gem_proc_list[i].name,
4452+ minor->dev_root);
4453+ return -1;
4454+ }
4455+ ent->read_proc = i915_gem_proc_list[i].f;
4456+ ent->data = minor;
4457+ }
4458+ return 0;
4459+}
4460+
4461+void i915_gem_proc_cleanup(struct drm_minor *minor)
4462+{
4463+ int i;
4464+
4465+ if (!minor->dev_root)
4466+ return;
4467+
4468+ for (i = 0; i < I915_GEM_PROC_ENTRIES; i++)
4469+ remove_proc_entry(i915_gem_proc_list[i].name, minor->dev_root);
4470+}
4471--- /dev/null
4472+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
4473@@ -0,0 +1,271 @@
4474+/*
4475+ * Copyright © 2008 Intel Corporation
4476+ *
4477+ * Permission is hereby granted, free of charge, to any person obtaining a
4478+ * copy of this software and associated documentation files (the "Software"),
4479+ * to deal in the Software without restriction, including without limitation
4480+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4481+ * and/or sell copies of the Software, and to permit persons to whom the
4482+ * Software is furnished to do so, subject to the following conditions:
4483+ *
4484+ * The above copyright notice and this permission notice (including the next
4485+ * paragraph) shall be included in all copies or substantial portions of the
4486+ * Software.
4487+ *
4488+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4489+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4490+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4491+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4492+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4493+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
4494+ * IN THE SOFTWARE.
4495+ *
4496+ * Authors:
4497+ * Eric Anholt <eric@anholt.net>
4498+ *
4499+ */
4500+
4501+#include "drmP.h"
4502+#include "drm.h"
4503+#include "i915_drm.h"
4504+#include "i915_drv.h"
4505+
4506+/** @file i915_gem_tiling.c
4507+ *
4508+ * Support for managing tiling state of buffer objects.
4509+ *
4510+ * The idea behind tiling is to increase cache hit rates by rearranging
4511+ * pixel data so that a group of pixel accesses are in the same cacheline.
4512+ * Performance improvement from doing this on the back/depth buffer are on
4513+ * the order of 30%.
4514+ *
4515+ * Intel architectures make this somewhat more complicated, though, by
4516+ * adjustments made to addressing of data when the memory is in interleaved
4517+ * mode (matched pairs of DIMMS) to improve memory bandwidth.
4518+ * For interleaved memory, the CPU sends every sequential 64 bytes
4519+ * to an alternate memory channel so it can get the bandwidth from both.
4520+ *
4521+ * The GPU also rearranges its accesses for increased bandwidth to interleaved
4522+ * memory, and it matches what the CPU does for non-tiled. However, when tiled
4523+ * it does it a little differently, since one walks addresses not just in the
4524+ * X direction but also Y. So, along with alternating channels when bit
4525+ * 6 of the address flips, it also alternates when other bits flip -- Bits 9
4526+ * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines)
4527+ * are common to both the 915 and 965-class hardware.
4528+ *
4529+ * The CPU also sometimes XORs in higher bits as well, to improve
4530+ * bandwidth doing strided access like we do so frequently in graphics. This
4531+ * is called "Channel XOR Randomization" in the MCH documentation. The result
4532+ * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address
4533+ * decode.
4534+ *
4535+ * All of this bit 6 XORing has an effect on our memory management,
4536+ * as we need to make sure that the 3d driver can correctly address object
4537+ * contents.
4538+ *
4539+ * If we don't have interleaved memory, all tiling is safe and no swizzling is
4540+ * required.
4541+ *
4542+ * When bit 17 is XORed in, we simply refuse to tile at all. Bit
4543+ * 17 is not just a page offset, so as we page an objet out and back in,
4544+ * individual pages in it will have different bit 17 addresses, resulting in
4545+ * each 64 bytes being swapped with its neighbor!
4546+ *
4547+ * Otherwise, if interleaved, we have to tell the 3d driver what the address
4548+ * swizzling it needs to do is, since it's writing with the CPU to the pages
4549+ * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the
4550+ * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling
4551+ * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order
4552+ * to match what the GPU expects.
4553+ */
4554+
4555+/**
4556+ * Detects bit 6 swizzling of address lookup between IGD access and CPU
4557+ * access through main memory.
4558+ */
4559+void
4560+i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
4561+{
4562+ drm_i915_private_t *dev_priv = dev->dev_private;
4563+ struct pci_dev *bridge;
4564+ uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4565+ uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4566+ int ret;
4567+
4568+ if (IS_I965G(dev) && !IS_I965GM(dev)) {
4569+ uint32_t chdecmisc;
4570+
4571+ /* On the 965, channel interleave appears to be determined by
4572+ * the flex bit. If flex is set, then the ranks (sides of a
4573+ * DIMM) of memory will be "stacked" (physical addresses walk
4574+ * through one rank then move on to the next, flipping channels
4575+ * or not depending on rank configuration). The GPU in this
4576+ * case does exactly the same addressing as the CPU.
4577+ *
4578+ * Unlike the 945, channel randomization based does not
4579+ * appear to be available.
4580+ *
4581+ * XXX: While the G965 doesn't appear to do any interleaving
4582+ * when the DIMMs are not exactly matched, the G4x chipsets
4583+ * might be for "L-shaped" configurations, and will need to be
4584+ * detected.
4585+ *
4586+ * L-shaped configuration:
4587+ *
4588+ * +-----+
4589+ * | |
4590+ * |DIMM2| <-- non-interleaved
4591+ * +-----+
4592+ * +-----+ +-----+
4593+ * | | | |
4594+ * |DIMM0| |DIMM1| <-- interleaved area
4595+ * +-----+ +-----+
4596+ */
4597+ chdecmisc = I915_READ(CHDECMISC);
4598+
4599+ if (chdecmisc == 0xff) {
4600+ DRM_ERROR("Couldn't read from MCHBAR. "
4601+ "Disabling tiling.\n");
4602+ } else if (chdecmisc & CHDECMISC_FLEXMEMORY) {
4603+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4604+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4605+ } else {
4606+ swizzle_x = I915_BIT_6_SWIZZLE_9_10;
4607+ swizzle_y = I915_BIT_6_SWIZZLE_9;
4608+ }
4609+ } else if (IS_I9XX(dev)) {
4610+ uint32_t dcc;
4611+
4612+ /* On 915-945 and GM965, channel interleave by the CPU is
4613+ * determined by DCC. The CPU will alternate based on bit 6
4614+ * in interleaved mode, and the GPU will then also alternate
4615+ * on bit 6, 9, and 10 for X, but the CPU may also optionally
4616+ * alternate based on bit 17 (XOR not disabled and XOR
4617+ * bit == 17).
4618+ */
4619+ dcc = I915_READ(DCC);
4620+ switch (dcc & DCC_ADDRESSING_MODE_MASK) {
4621+ case DCC_ADDRESSING_MODE_SINGLE_CHANNEL:
4622+ case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC:
4623+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4624+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4625+ break;
4626+ case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
4627+ if (IS_I915G(dev) || IS_I915GM(dev) ||
4628+ dcc & DCC_CHANNEL_XOR_DISABLE) {
4629+ swizzle_x = I915_BIT_6_SWIZZLE_9_10;
4630+ swizzle_y = I915_BIT_6_SWIZZLE_9;
4631+ } else if (IS_I965GM(dev)) {
4632+ /* GM965 only does bit 11-based channel
4633+ * randomization
4634+ */
4635+ swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
4636+ swizzle_y = I915_BIT_6_SWIZZLE_9_11;
4637+ } else {
4638+ /* Bit 17 or perhaps other swizzling */
4639+ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4640+ swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4641+ }
4642+ break;
4643+ }
4644+ if (dcc == 0xffffffff) {
4645+ DRM_ERROR("Couldn't read from MCHBAR. "
4646+ "Disabling tiling.\n");
4647+ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4648+ swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4649+ }
4650+ } else {
4651+ /* As far as we know, the 865 doesn't have these bit 6
4652+ * swizzling issues.
4653+ */
4654+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4655+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4656+ }
4657+
4658+ dev_priv->mm.bit_6_swizzle_x = swizzle_x;
4659+ dev_priv->mm.bit_6_swizzle_y = swizzle_y;
4660+}
4661+
4662+/**
4663+ * Sets the tiling mode of an object, returning the required swizzling of
4664+ * bit 6 of addresses in the object.
4665+ */
4666+int
4667+i915_gem_set_tiling(struct drm_device *dev, void *data,
4668+ struct drm_file *file_priv)
4669+{
4670+ struct drm_i915_gem_set_tiling *args = data;
4671+ drm_i915_private_t *dev_priv = dev->dev_private;
4672+ struct drm_gem_object *obj;
4673+ struct drm_i915_gem_object *obj_priv;
4674+
4675+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4676+ if (obj == NULL)
4677+ return -EINVAL;
4678+ obj_priv = obj->driver_private;
4679+
4680+ mutex_lock(&dev->struct_mutex);
4681+
4682+ if (args->tiling_mode == I915_TILING_NONE) {
4683+ obj_priv->tiling_mode = I915_TILING_NONE;
4684+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4685+ } else {
4686+ if (args->tiling_mode == I915_TILING_X)
4687+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
4688+ else
4689+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
4690+ /* If we can't handle the swizzling, make it untiled. */
4691+ if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
4692+ args->tiling_mode = I915_TILING_NONE;
4693+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4694+ }
4695+ }
4696+ obj_priv->tiling_mode = args->tiling_mode;
4697+
4698+ mutex_unlock(&dev->struct_mutex);
4699+
4700+ drm_gem_object_unreference(obj);
4701+
4702+ return 0;
4703+}
4704+
4705+/**
4706+ * Returns the current tiling mode and required bit 6 swizzling for the object.
4707+ */
4708+int
4709+i915_gem_get_tiling(struct drm_device *dev, void *data,
4710+ struct drm_file *file_priv)
4711+{
4712+ struct drm_i915_gem_get_tiling *args = data;
4713+ drm_i915_private_t *dev_priv = dev->dev_private;
4714+ struct drm_gem_object *obj;
4715+ struct drm_i915_gem_object *obj_priv;
4716+
4717+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4718+ if (obj == NULL)
4719+ return -EINVAL;
4720+ obj_priv = obj->driver_private;
4721+
4722+ mutex_lock(&dev->struct_mutex);
4723+
4724+ args->tiling_mode = obj_priv->tiling_mode;
4725+ switch (obj_priv->tiling_mode) {
4726+ case I915_TILING_X:
4727+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
4728+ break;
4729+ case I915_TILING_Y:
4730+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
4731+ break;
4732+ case I915_TILING_NONE:
4733+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4734+ break;
4735+ default:
4736+ DRM_ERROR("unknown tiling mode\n");
4737+ }
4738+
4739+ mutex_unlock(&dev->struct_mutex);
4740+
4741+ drm_gem_object_unreference(obj);
4742+
4743+ return 0;
4744+}
4745--- a/drivers/gpu/drm/i915/i915_irq.c
4746+++ b/drivers/gpu/drm/i915/i915_irq.c
4747@@ -281,8 +281,10 @@ irqreturn_t i915_driver_irq_handler(DRM_
4748
4749 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
4750
4751- if (iir & I915_USER_INTERRUPT)
4752+ if (iir & I915_USER_INTERRUPT) {
4753+ dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
4754 DRM_WAKEUP(&dev_priv->irq_queue);
4755+ }
4756
4757 if (iir & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
4758 I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
4759@@ -343,7 +345,7 @@ static int i915_emit_irq(struct drm_devi
4760 return dev_priv->counter;
4761 }
4762
4763-static void i915_user_irq_get(struct drm_device *dev)
4764+void i915_user_irq_get(struct drm_device *dev)
4765 {
4766 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
4767
4768@@ -353,7 +355,7 @@ static void i915_user_irq_get(struct drm
4769 spin_unlock(&dev_priv->user_irq_lock);
4770 }
4771
4772-static void i915_user_irq_put(struct drm_device *dev)
4773+void i915_user_irq_put(struct drm_device *dev)
4774 {
4775 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
4776
4777--- a/drivers/gpu/drm/i915/i915_reg.h
4778+++ b/drivers/gpu/drm/i915/i915_reg.h
4779@@ -25,19 +25,6 @@
4780 #ifndef _I915_REG_H_
4781 #define _I915_REG_H_
4782
4783-/* MCH MMIO space */
4784-/** 915-945 and GM965 MCH register controlling DRAM channel access */
4785-#define DCC 0x200
4786-#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
4787-#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
4788-#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
4789-#define DCC_ADDRESSING_MODE_MASK (3 << 0)
4790-#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
4791-
4792-/** 965 MCH register controlling DRAM channel configuration */
4793-#define CHDECMISC 0x111
4794-#define CHDECMISC_FLEXMEMORY (1 << 1)
4795-
4796 /*
4797 * The Bridge device's PCI config space has information about the
4798 * fb aperture size and the amount of pre-reserved memory.
4799@@ -516,6 +503,30 @@
4800 #define PALETTE_A 0x0a000
4801 #define PALETTE_B 0x0a800
4802
4803+/* MCH MMIO space */
4804+
4805+/*
4806+ * MCHBAR mirror.
4807+ *
4808+ * This mirrors the MCHBAR MMIO space whose location is determined by
4809+ * device 0 function 0's pci config register 0x44 or 0x48 and matches it in
4810+ * every way. It is not accessible from the CP register read instructions.
4811+ *
4812+ */
4813+/** 915-945 and GM965 MCH register controlling DRAM channel access */
4814+#define MCHBAR_MIRROR_BASE 0x10000
4815+
4816+#define DCC 0x10200
4817+#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
4818+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
4819+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
4820+#define DCC_ADDRESSING_MODE_MASK (3 << 0)
4821+#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
4822+
4823+/** 965 MCH register controlling DRAM channel configuration */
4824+#define CHDECMISC 0x10111
4825+#define CHDECMISC_FLEXMEMORY (1 << 1)
4826+
4827 /*
4828 * Overlay regs
4829 */
4830--- a/include/drm/drm.h
4831+++ b/include/drm/drm.h
4832@@ -573,6 +573,34 @@ struct drm_set_version {
4833 int drm_dd_minor;
4834 };
4835
4836+/** DRM_IOCTL_GEM_CLOSE ioctl argument type */
4837+struct drm_gem_close {
4838+ /** Handle of the object to be closed. */
4839+ uint32_t handle;
4840+ uint32_t pad;
4841+};
4842+
4843+/** DRM_IOCTL_GEM_FLINK ioctl argument type */
4844+struct drm_gem_flink {
4845+ /** Handle for the object being named */
4846+ uint32_t handle;
4847+
4848+ /** Returned global name */
4849+ uint32_t name;
4850+};
4851+
4852+/** DRM_IOCTL_GEM_OPEN ioctl argument type */
4853+struct drm_gem_open {
4854+ /** Name of object being opened */
4855+ uint32_t name;
4856+
4857+ /** Returned handle for the object */
4858+ uint32_t handle;
4859+
4860+ /** Returned size of the object */
4861+ uint64_t size;
4862+};
4863+
4864 #define DRM_IOCTL_BASE 'd'
4865 #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
4866 #define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
4867@@ -587,6 +615,9 @@ struct drm_set_version {
4868 #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
4869 #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
4870 #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
4871+#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close)
4872+#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink)
4873+#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open)
4874
4875 #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
4876 #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
4877--- a/include/drm/drmP.h
4878+++ b/include/drm/drmP.h
4879@@ -104,6 +104,7 @@ struct drm_device;
4880 #define DRIVER_DMA_QUEUE 0x200
4881 #define DRIVER_FB_DMA 0x400
4882 #define DRIVER_IRQ_VBL2 0x800
4883+#define DRIVER_GEM 0x1000
4884
4885 /***********************************************************************/
4886 /** \name Begin the DRM... */
4887@@ -387,6 +388,10 @@ struct drm_file {
4888 struct drm_minor *minor;
4889 int remove_auth_on_close;
4890 unsigned long lock_count;
4891+ /** Mapping of mm object handles to object pointers. */
4892+ struct idr object_idr;
4893+ /** Lock for synchronization of access to object_idr. */
4894+ spinlock_t table_lock;
4895 struct file *filp;
4896 void *driver_priv;
4897 };
4898@@ -558,6 +563,56 @@ struct drm_ati_pcigart_info {
4899 };
4900
4901 /**
4902+ * This structure defines the drm_mm memory object, which will be used by the
4903+ * DRM for its buffer objects.
4904+ */
4905+struct drm_gem_object {
4906+ /** Reference count of this object */
4907+ struct kref refcount;
4908+
4909+ /** Handle count of this object. Each handle also holds a reference */
4910+ struct kref handlecount;
4911+
4912+ /** Related drm device */
4913+ struct drm_device *dev;
4914+
4915+ /** File representing the shmem storage */
4916+ struct file *filp;
4917+
4918+ /**
4919+ * Size of the object, in bytes. Immutable over the object's
4920+ * lifetime.
4921+ */
4922+ size_t size;
4923+
4924+ /**
4925+ * Global name for this object, starts at 1. 0 means unnamed.
4926+ * Access is covered by the object_name_lock in the related drm_device
4927+ */
4928+ int name;
4929+
4930+ /**
4931+ * Memory domains. These monitor which caches contain read/write data
4932+ * related to the object. When transitioning from one set of domains
4933+ * to another, the driver is called to ensure that caches are suitably
4934+ * flushed and invalidated
4935+ */
4936+ uint32_t read_domains;
4937+ uint32_t write_domain;
4938+
4939+ /**
4940+ * While validating an exec operation, the
4941+ * new read/write domain values are computed here.
4942+ * They will be transferred to the above values
4943+ * at the point that any cache flushing occurs
4944+ */
4945+ uint32_t pending_read_domains;
4946+ uint32_t pending_write_domain;
4947+
4948+ void *driver_private;
4949+};
4950+
4951+/**
4952 * DRM driver structure. This structure represent the common code for
4953 * a family of cards. There will one drm_device for each card present
4954 * in this family
4955@@ -614,6 +669,18 @@ struct drm_driver {
4956 void (*set_version) (struct drm_device *dev,
4957 struct drm_set_version *sv);
4958
4959+ int (*proc_init)(struct drm_minor *minor);
4960+ void (*proc_cleanup)(struct drm_minor *minor);
4961+
4962+ /**
4963+ * Driver-specific constructor for drm_gem_objects, to set up
4964+ * obj->driver_private.
4965+ *
4966+ * Returns 0 on success.
4967+ */
4968+ int (*gem_init_object) (struct drm_gem_object *obj);
4969+ void (*gem_free_object) (struct drm_gem_object *obj);
4970+
4971 int major;
4972 int minor;
4973 int patchlevel;
4974@@ -771,6 +838,22 @@ struct drm_device {
4975 spinlock_t drw_lock;
4976 struct idr drw_idr;
4977 /*@} */
4978+
4979+ /** \name GEM information */
4980+ /*@{ */
4981+ spinlock_t object_name_lock;
4982+ struct idr object_name_idr;
4983+ atomic_t object_count;
4984+ atomic_t object_memory;
4985+ atomic_t pin_count;
4986+ atomic_t pin_memory;
4987+ atomic_t gtt_count;
4988+ atomic_t gtt_memory;
4989+ uint32_t gtt_total;
4990+ uint32_t invalidate_domains; /* domains pending invalidation */
4991+ uint32_t flush_domains; /* domains pending flush */
4992+ /*@} */
4993+
4994 };
4995
4996 static __inline__ int drm_core_check_feature(struct drm_device *dev,
4997@@ -867,6 +950,10 @@ extern void *drm_realloc(void *oldpt, si
4998 extern DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type);
4999 extern int drm_free_agp(DRM_AGP_MEM * handle, int pages);
5000 extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start);
5001+extern DRM_AGP_MEM *drm_agp_bind_pages(struct drm_device *dev,
5002+ struct page **pages,
5003+ unsigned long num_pages,
5004+ uint32_t gtt_offset);
5005 extern int drm_unbind_agp(DRM_AGP_MEM * handle);
5006
5007 /* Misc. IOCTL support (drm_ioctl.h) */
5008@@ -929,6 +1016,9 @@ extern int drm_getmagic(struct drm_devic
5009 extern int drm_authmagic(struct drm_device *dev, void *data,
5010 struct drm_file *file_priv);
5011
5012+/* Cache management (drm_cache.c) */
5013+void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
5014+
5015 /* Locking IOCTL support (drm_lock.h) */
5016 extern int drm_lock(struct drm_device *dev, void *data,
5017 struct drm_file *file_priv);
5018@@ -1026,6 +1116,7 @@ extern DRM_AGP_MEM *drm_agp_allocate_mem
5019 extern int drm_agp_free_memory(DRM_AGP_MEM * handle);
5020 extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start);
5021 extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
5022+extern void drm_agp_chipset_flush(struct drm_device *dev);
5023
5024 /* Stub support (drm_stub.h) */
5025 extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
5026@@ -1088,6 +1179,66 @@ extern unsigned long drm_mm_tail_space(s
5027 extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size);
5028 extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size);
5029
5030+/* Graphics Execution Manager library functions (drm_gem.c) */
5031+int drm_gem_init(struct drm_device *dev);
5032+void drm_gem_object_free(struct kref *kref);
5033+struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev,
5034+ size_t size);
5035+void drm_gem_object_handle_free(struct kref *kref);
5036+
5037+static inline void
5038+drm_gem_object_reference(struct drm_gem_object *obj)
5039+{
5040+ kref_get(&obj->refcount);
5041+}
5042+
5043+static inline void
5044+drm_gem_object_unreference(struct drm_gem_object *obj)
5045+{
5046+ if (obj == NULL)
5047+ return;
5048+
5049+ kref_put(&obj->refcount, drm_gem_object_free);
5050+}
5051+
5052+int drm_gem_handle_create(struct drm_file *file_priv,
5053+ struct drm_gem_object *obj,
5054+ int *handlep);
5055+
5056+static inline void
5057+drm_gem_object_handle_reference(struct drm_gem_object *obj)
5058+{
5059+ drm_gem_object_reference(obj);
5060+ kref_get(&obj->handlecount);
5061+}
5062+
5063+static inline void
5064+drm_gem_object_handle_unreference(struct drm_gem_object *obj)
5065+{
5066+ if (obj == NULL)
5067+ return;
5068+
5069+ /*
5070+ * Must bump handle count first as this may be the last
5071+ * ref, in which case the object would disappear before we
5072+ * checked for a name
5073+ */
5074+ kref_put(&obj->handlecount, drm_gem_object_handle_free);
5075+ drm_gem_object_unreference(obj);
5076+}
5077+
5078+struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev,
5079+ struct drm_file *filp,
5080+ int handle);
5081+int drm_gem_close_ioctl(struct drm_device *dev, void *data,
5082+ struct drm_file *file_priv);
5083+int drm_gem_flink_ioctl(struct drm_device *dev, void *data,
5084+ struct drm_file *file_priv);
5085+int drm_gem_open_ioctl(struct drm_device *dev, void *data,
5086+ struct drm_file *file_priv);
5087+void drm_gem_open(struct drm_device *dev, struct drm_file *file_private);
5088+void drm_gem_release(struct drm_device *dev, struct drm_file *file_private);
5089+
5090 extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev);
5091 extern void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev);
5092 extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev);
5093--- a/include/drm/i915_drm.h
5094+++ b/include/drm/i915_drm.h
5095@@ -143,6 +143,22 @@ typedef struct _drm_i915_sarea {
5096 #define DRM_I915_GET_VBLANK_PIPE 0x0e
5097 #define DRM_I915_VBLANK_SWAP 0x0f
5098 #define DRM_I915_HWS_ADDR 0x11
5099+#define DRM_I915_GEM_INIT 0x13
5100+#define DRM_I915_GEM_EXECBUFFER 0x14
5101+#define DRM_I915_GEM_PIN 0x15
5102+#define DRM_I915_GEM_UNPIN 0x16
5103+#define DRM_I915_GEM_BUSY 0x17
5104+#define DRM_I915_GEM_THROTTLE 0x18
5105+#define DRM_I915_GEM_ENTERVT 0x19
5106+#define DRM_I915_GEM_LEAVEVT 0x1a
5107+#define DRM_I915_GEM_CREATE 0x1b
5108+#define DRM_I915_GEM_PREAD 0x1c
5109+#define DRM_I915_GEM_PWRITE 0x1d
5110+#define DRM_I915_GEM_MMAP 0x1e
5111+#define DRM_I915_GEM_SET_DOMAIN 0x1f
5112+#define DRM_I915_GEM_SW_FINISH 0x20
5113+#define DRM_I915_GEM_SET_TILING 0x21
5114+#define DRM_I915_GEM_GET_TILING 0x22
5115
5116 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
5117 #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
5118@@ -160,6 +176,20 @@ typedef struct _drm_i915_sarea {
5119 #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
5120 #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
5121 #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
5122+#define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
5123+#define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
5124+#define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
5125+#define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE)
5126+#define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
5127+#define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
5128+#define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
5129+#define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
5130+#define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
5131+#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
5132+#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
5133+#define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
5134+#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
5135+#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
5136
5137 /* Allow drivers to submit batchbuffers directly to hardware, relying
5138 * on the security mechanisms provided by hardware.
5139@@ -200,6 +230,7 @@ typedef struct drm_i915_irq_wait {
5140 #define I915_PARAM_IRQ_ACTIVE 1
5141 #define I915_PARAM_ALLOW_BATCHBUFFER 2
5142 #define I915_PARAM_LAST_DISPATCH 3
5143+#define I915_PARAM_HAS_GEM 5
5144
5145 typedef struct drm_i915_getparam {
5146 int param;
5147@@ -267,4 +298,305 @@ typedef struct drm_i915_hws_addr {
5148 uint64_t addr;
5149 } drm_i915_hws_addr_t;
5150
5151+struct drm_i915_gem_init {
5152+ /**
5153+ * Beginning offset in the GTT to be managed by the DRM memory
5154+ * manager.
5155+ */
5156+ uint64_t gtt_start;
5157+ /**
5158+ * Ending offset in the GTT to be managed by the DRM memory
5159+ * manager.
5160+ */
5161+ uint64_t gtt_end;
5162+};
5163+
5164+struct drm_i915_gem_create {
5165+ /**
5166+ * Requested size for the object.
5167+ *
5168+ * The (page-aligned) allocated size for the object will be returned.
5169+ */
5170+ uint64_t size;
5171+ /**
5172+ * Returned handle for the object.
5173+ *
5174+ * Object handles are nonzero.
5175+ */
5176+ uint32_t handle;
5177+ uint32_t pad;
5178+};
5179+
5180+struct drm_i915_gem_pread {
5181+ /** Handle for the object being read. */
5182+ uint32_t handle;
5183+ uint32_t pad;
5184+ /** Offset into the object to read from */
5185+ uint64_t offset;
5186+ /** Length of data to read */
5187+ uint64_t size;
5188+ /**
5189+ * Pointer to write the data into.
5190+ *
5191+ * This is a fixed-size type for 32/64 compatibility.
5192+ */
5193+ uint64_t data_ptr;
5194+};
5195+
5196+struct drm_i915_gem_pwrite {
5197+ /** Handle for the object being written to. */
5198+ uint32_t handle;
5199+ uint32_t pad;
5200+ /** Offset into the object to write to */
5201+ uint64_t offset;
5202+ /** Length of data to write */
5203+ uint64_t size;
5204+ /**
5205+ * Pointer to read the data from.
5206+ *
5207+ * This is a fixed-size type for 32/64 compatibility.
5208+ */
5209+ uint64_t data_ptr;
5210+};
5211+
5212+struct drm_i915_gem_mmap {
5213+ /** Handle for the object being mapped. */
5214+ uint32_t handle;
5215+ uint32_t pad;
5216+ /** Offset in the object to map. */
5217+ uint64_t offset;
5218+ /**
5219+ * Length of data to map.
5220+ *
5221+ * The value will be page-aligned.
5222+ */
5223+ uint64_t size;
5224+ /**
5225+ * Returned pointer the data was mapped at.
5226+ *
5227+ * This is a fixed-size type for 32/64 compatibility.
5228+ */
5229+ uint64_t addr_ptr;
5230+};
5231+
5232+struct drm_i915_gem_set_domain {
5233+ /** Handle for the object */
5234+ uint32_t handle;
5235+
5236+ /** New read domains */
5237+ uint32_t read_domains;
5238+
5239+ /** New write domain */
5240+ uint32_t write_domain;
5241+};
5242+
5243+struct drm_i915_gem_sw_finish {
5244+ /** Handle for the object */
5245+ uint32_t handle;
5246+};
5247+
5248+struct drm_i915_gem_relocation_entry {
5249+ /**
5250+ * Handle of the buffer being pointed to by this relocation entry.
5251+ *
5252+ * It's appealing to make this be an index into the mm_validate_entry
5253+ * list to refer to the buffer, but this allows the driver to create
5254+ * a relocation list for state buffers and not re-write it per
5255+ * exec using the buffer.
5256+ */
5257+ uint32_t target_handle;
5258+
5259+ /**
5260+ * Value to be added to the offset of the target buffer to make up
5261+ * the relocation entry.
5262+ */
5263+ uint32_t delta;
5264+
5265+ /** Offset in the buffer the relocation entry will be written into */
5266+ uint64_t offset;
5267+
5268+ /**
5269+ * Offset value of the target buffer that the relocation entry was last
5270+ * written as.
5271+ *
5272+ * If the buffer has the same offset as last time, we can skip syncing
5273+ * and writing the relocation. This value is written back out by
5274+ * the execbuffer ioctl when the relocation is written.
5275+ */
5276+ uint64_t presumed_offset;
5277+
5278+ /**
5279+ * Target memory domains read by this operation.
5280+ */
5281+ uint32_t read_domains;
5282+
5283+ /**
5284+ * Target memory domains written by this operation.
5285+ *
5286+ * Note that only one domain may be written by the whole
5287+ * execbuffer operation, so that where there are conflicts,
5288+ * the application will get -EINVAL back.
5289+ */
5290+ uint32_t write_domain;
5291+};
5292+
5293+/** @{
5294+ * Intel memory domains
5295+ *
5296+ * Most of these just align with the various caches in
5297+ * the system and are used to flush and invalidate as
5298+ * objects end up cached in different domains.
5299+ */
5300+/** CPU cache */
5301+#define I915_GEM_DOMAIN_CPU 0x00000001
5302+/** Render cache, used by 2D and 3D drawing */
5303+#define I915_GEM_DOMAIN_RENDER 0x00000002
5304+/** Sampler cache, used by texture engine */
5305+#define I915_GEM_DOMAIN_SAMPLER 0x00000004
5306+/** Command queue, used to load batch buffers */
5307+#define I915_GEM_DOMAIN_COMMAND 0x00000008
5308+/** Instruction cache, used by shader programs */
5309+#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010
5310+/** Vertex address cache */
5311+#define I915_GEM_DOMAIN_VERTEX 0x00000020
5312+/** GTT domain - aperture and scanout */
5313+#define I915_GEM_DOMAIN_GTT 0x00000040
5314+/** @} */
5315+
5316+struct drm_i915_gem_exec_object {
5317+ /**
5318+ * User's handle for a buffer to be bound into the GTT for this
5319+ * operation.
5320+ */
5321+ uint32_t handle;
5322+
5323+ /** Number of relocations to be performed on this buffer */
5324+ uint32_t relocation_count;
5325+ /**
5326+ * Pointer to array of struct drm_i915_gem_relocation_entry containing
5327+ * the relocations to be performed in this buffer.
5328+ */
5329+ uint64_t relocs_ptr;
5330+
5331+ /** Required alignment in graphics aperture */
5332+ uint64_t alignment;
5333+
5334+ /**
5335+ * Returned value of the updated offset of the object, for future
5336+ * presumed_offset writes.
5337+ */
5338+ uint64_t offset;
5339+};
5340+
5341+struct drm_i915_gem_execbuffer {
5342+ /**
5343+ * List of buffers to be validated with their relocations to be
5344+ * performend on them.
5345+ *
5346+ * This is a pointer to an array of struct drm_i915_gem_validate_entry.
5347+ *
5348+ * These buffers must be listed in an order such that all relocations
5349+ * a buffer is performing refer to buffers that have already appeared
5350+ * in the validate list.
5351+ */
5352+ uint64_t buffers_ptr;
5353+ uint32_t buffer_count;
5354+
5355+ /** Offset in the batchbuffer to start execution from. */
5356+ uint32_t batch_start_offset;
5357+ /** Bytes used in batchbuffer from batch_start_offset */
5358+ uint32_t batch_len;
5359+ uint32_t DR1;
5360+ uint32_t DR4;
5361+ uint32_t num_cliprects;
5362+ /** This is a struct drm_clip_rect *cliprects */
5363+ uint64_t cliprects_ptr;
5364+};
5365+
5366+struct drm_i915_gem_pin {
5367+ /** Handle of the buffer to be pinned. */
5368+ uint32_t handle;
5369+ uint32_t pad;
5370+
5371+ /** alignment required within the aperture */
5372+ uint64_t alignment;
5373+
5374+ /** Returned GTT offset of the buffer. */
5375+ uint64_t offset;
5376+};
5377+
5378+struct drm_i915_gem_unpin {
5379+ /** Handle of the buffer to be unpinned. */
5380+ uint32_t handle;
5381+ uint32_t pad;
5382+};
5383+
5384+struct drm_i915_gem_busy {
5385+ /** Handle of the buffer to check for busy */
5386+ uint32_t handle;
5387+
5388+ /** Return busy status (1 if busy, 0 if idle) */
5389+ uint32_t busy;
5390+};
5391+
5392+#define I915_TILING_NONE 0
5393+#define I915_TILING_X 1
5394+#define I915_TILING_Y 2
5395+
5396+#define I915_BIT_6_SWIZZLE_NONE 0
5397+#define I915_BIT_6_SWIZZLE_9 1
5398+#define I915_BIT_6_SWIZZLE_9_10 2
5399+#define I915_BIT_6_SWIZZLE_9_11 3
5400+#define I915_BIT_6_SWIZZLE_9_10_11 4
5401+/* Not seen by userland */
5402+#define I915_BIT_6_SWIZZLE_UNKNOWN 5
5403+
5404+struct drm_i915_gem_set_tiling {
5405+ /** Handle of the buffer to have its tiling state updated */
5406+ uint32_t handle;
5407+
5408+ /**
5409+ * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
5410+ * I915_TILING_Y).
5411+ *
5412+ * This value is to be set on request, and will be updated by the
5413+ * kernel on successful return with the actual chosen tiling layout.
5414+ *
5415+ * The tiling mode may be demoted to I915_TILING_NONE when the system
5416+ * has bit 6 swizzling that can't be managed correctly by GEM.
5417+ *
5418+ * Buffer contents become undefined when changing tiling_mode.
5419+ */
5420+ uint32_t tiling_mode;
5421+
5422+ /**
5423+ * Stride in bytes for the object when in I915_TILING_X or
5424+ * I915_TILING_Y.
5425+ */
5426+ uint32_t stride;
5427+
5428+ /**
5429+ * Returned address bit 6 swizzling required for CPU access through
5430+ * mmap mapping.
5431+ */
5432+ uint32_t swizzle_mode;
5433+};
5434+
5435+struct drm_i915_gem_get_tiling {
5436+ /** Handle of the buffer to get tiling state for. */
5437+ uint32_t handle;
5438+
5439+ /**
5440+ * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
5441+ * I915_TILING_Y).
5442+ */
5443+ uint32_t tiling_mode;
5444+
5445+ /**
5446+ * Returned address bit 6 swizzling required for CPU access through
5447+ * mmap mapping.
5448+ */
5449+ uint32_t swizzle_mode;
5450+};
5451+
5452 #endif /* _I915_DRM_H_ */
5453
diff --git a/meta/packages/linux/linux-moblin2-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch
new file mode 100644
index 0000000000..4de9839c76
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch
@@ -0,0 +1,6727 @@
1diff -uNr a/fs/Kconfig b/fs/Kconfig
2--- a/fs/Kconfig 2008-07-28 19:40:31.000000000 -0700
3+++ b/fs/Kconfig 2008-08-13 16:19:56.000000000 -0700
4@@ -1348,6 +1348,56 @@
5
6 If unsure, say N.
7
8+config SQUASHFS
9+ tristate "SquashFS 3.3 - Squashed file system support"
10+ select ZLIB_INFLATE
11+ help
12+ Saying Y here includes support for SquashFS 3.3 (a Compressed
13+ Read-Only File System). Squashfs is a highly compressed read-only
14+ filesystem for Linux. It uses zlib compression to compress both
15+ files, inodes and directories. Inodes in the system are very small
16+ and all blocks are packed to minimise data overhead. Block sizes
17+ greater than 4K are supported up to a maximum of 1 Mbytes (default
18+ block size 128K). SquashFS 3.3 supports 64 bit filesystems and files
19+ (larger than 4GB), full uid/gid information, hard links and timestamps.
20+
21+ Squashfs is intended for general read-only filesystem use, for
22+ archival use (i.e. in cases where a .tar.gz file may be used), and in
23+ embedded systems where low overhead is needed. Further information
24+ and filesystem tools are available from http://squashfs.sourceforge.net.
25+
26+ If you want to compile this as a module ( = code which can be
27+ inserted in and removed from the running kernel whenever you want),
28+ say M here and read <file:Documentation/modules.txt>. The module
29+ will be called squashfs. Note that the root file system (the one
30+ containing the directory /) cannot be compiled as a module.
31+
32+ If unsure, say N.
33+
34+config SQUASHFS_EMBEDDED
35+
36+ bool "Additional option for memory-constrained systems"
37+ depends on SQUASHFS
38+ default n
39+ help
40+ Saying Y here allows you to specify cache size.
41+
42+ If unsure, say N.
43+
44+config SQUASHFS_FRAGMENT_CACHE_SIZE
45+ int "Number of fragments cached" if SQUASHFS_EMBEDDED
46+ depends on SQUASHFS
47+ default "3"
48+ help
49+ By default SquashFS caches the last 3 fragments read from
50+ the filesystem. Increasing this amount may mean SquashFS
51+ has to re-read fragments less often from disk, at the expense
52+ of extra system memory. Decreasing this amount will mean
53+ SquashFS uses less memory at the expense of extra reads from disk.
54+
55+ Note there must be at least one cached fragment. Anything
56+ much more than three will probably not make much difference.
57+
58 config VXFS_FS
59 tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
60 depends on BLOCK
61diff -uNr a/fs/Kconfig.orig b/fs/Kconfig.orig
62--- a/fs/Kconfig.orig 1969-12-31 16:00:00.000000000 -0800
63+++ b/fs/Kconfig.orig 2008-07-28 19:40:31.000000000 -0700
64@@ -0,0 +1,2097 @@
65+#
66+# File system configuration
67+#
68+
69+menu "File systems"
70+
71+if BLOCK
72+
73+config EXT2_FS
74+ tristate "Second extended fs support"
75+ help
76+ Ext2 is a standard Linux file system for hard disks.
77+
78+ To compile this file system support as a module, choose M here: the
79+ module will be called ext2.
80+
81+ If unsure, say Y.
82+
83+config EXT2_FS_XATTR
84+ bool "Ext2 extended attributes"
85+ depends on EXT2_FS
86+ help
87+ Extended attributes are name:value pairs associated with inodes by
88+ the kernel or by users (see the attr(5) manual page, or visit
89+ <http://acl.bestbits.at/> for details).
90+
91+ If unsure, say N.
92+
93+config EXT2_FS_POSIX_ACL
94+ bool "Ext2 POSIX Access Control Lists"
95+ depends on EXT2_FS_XATTR
96+ select FS_POSIX_ACL
97+ help
98+ Posix Access Control Lists (ACLs) support permissions for users and
99+ groups beyond the owner/group/world scheme.
100+
101+ To learn more about Access Control Lists, visit the Posix ACLs for
102+ Linux website <http://acl.bestbits.at/>.
103+
104+ If you don't know what Access Control Lists are, say N
105+
106+config EXT2_FS_SECURITY
107+ bool "Ext2 Security Labels"
108+ depends on EXT2_FS_XATTR
109+ help
110+ Security labels support alternative access control models
111+ implemented by security modules like SELinux. This option
112+ enables an extended attribute handler for file security
113+ labels in the ext2 filesystem.
114+
115+ If you are not using a security module that requires using
116+ extended attributes for file security labels, say N.
117+
118+config EXT2_FS_XIP
119+ bool "Ext2 execute in place support"
120+ depends on EXT2_FS && MMU
121+ help
122+ Execute in place can be used on memory-backed block devices. If you
123+ enable this option, you can select to mount block devices which are
124+ capable of this feature without using the page cache.
125+
126+ If you do not use a block device that is capable of using this,
127+ or if unsure, say N.
128+
129+config FS_XIP
130+# execute in place
131+ bool
132+ depends on EXT2_FS_XIP
133+ default y
134+
135+config EXT3_FS
136+ tristate "Ext3 journalling file system support"
137+ select JBD
138+ help
139+ This is the journalling version of the Second extended file system
140+ (often called ext3), the de facto standard Linux file system
141+ (method to organize files on a storage device) for hard disks.
142+
143+ The journalling code included in this driver means you do not have
144+ to run e2fsck (file system checker) on your file systems after a
145+ crash. The journal keeps track of any changes that were being made
146+ at the time the system crashed, and can ensure that your file system
147+ is consistent without the need for a lengthy check.
148+
149+ Other than adding the journal to the file system, the on-disk format
150+ of ext3 is identical to ext2. It is possible to freely switch
151+ between using the ext3 driver and the ext2 driver, as long as the
152+ file system has been cleanly unmounted, or e2fsck is run on the file
153+ system.
154+
155+ To add a journal on an existing ext2 file system or change the
156+ behavior of ext3 file systems, you can use the tune2fs utility ("man
157+ tune2fs"). To modify attributes of files and directories on ext3
158+ file systems, use chattr ("man chattr"). You need to be using
159+ e2fsprogs version 1.20 or later in order to create ext3 journals
160+ (available at <http://sourceforge.net/projects/e2fsprogs/>).
161+
162+ To compile this file system support as a module, choose M here: the
163+ module will be called ext3.
164+
165+config EXT3_FS_XATTR
166+ bool "Ext3 extended attributes"
167+ depends on EXT3_FS
168+ default y
169+ help
170+ Extended attributes are name:value pairs associated with inodes by
171+ the kernel or by users (see the attr(5) manual page, or visit
172+ <http://acl.bestbits.at/> for details).
173+
174+ If unsure, say N.
175+
176+ You need this for POSIX ACL support on ext3.
177+
178+config EXT3_FS_POSIX_ACL
179+ bool "Ext3 POSIX Access Control Lists"
180+ depends on EXT3_FS_XATTR
181+ select FS_POSIX_ACL
182+ help
183+ Posix Access Control Lists (ACLs) support permissions for users and
184+ groups beyond the owner/group/world scheme.
185+
186+ To learn more about Access Control Lists, visit the Posix ACLs for
187+ Linux website <http://acl.bestbits.at/>.
188+
189+ If you don't know what Access Control Lists are, say N
190+
191+config EXT3_FS_SECURITY
192+ bool "Ext3 Security Labels"
193+ depends on EXT3_FS_XATTR
194+ help
195+ Security labels support alternative access control models
196+ implemented by security modules like SELinux. This option
197+ enables an extended attribute handler for file security
198+ labels in the ext3 filesystem.
199+
200+ If you are not using a security module that requires using
201+ extended attributes for file security labels, say N.
202+
203+config EXT4DEV_FS
204+ tristate "Ext4dev/ext4 extended fs support development (EXPERIMENTAL)"
205+ depends on EXPERIMENTAL
206+ select JBD2
207+ select CRC16
208+ help
209+ Ext4dev is a predecessor filesystem of the next generation
210+ extended fs ext4, based on ext3 filesystem code. It will be
211+ renamed ext4 fs later, once ext4dev is mature and stabilized.
212+
213+ Unlike the change from ext2 filesystem to ext3 filesystem,
214+ the on-disk format of ext4dev is not the same as ext3 any more:
215+ it is based on extent maps and it supports 48-bit physical block
216+ numbers. These combined on-disk format changes will allow
217+ ext4dev/ext4 to handle more than 16 TB filesystem volumes --
218+ a hard limit that ext3 cannot overcome without changing the
219+ on-disk format.
220+
221+ Other than extent maps and 48-bit block numbers, ext4dev also is
222+ likely to have other new features such as persistent preallocation,
223+ high resolution time stamps, and larger file support etc. These
224+ features will be added to ext4dev gradually.
225+
226+ To compile this file system support as a module, choose M here. The
227+ module will be called ext4dev.
228+
229+ If unsure, say N.
230+
231+config EXT4DEV_FS_XATTR
232+ bool "Ext4dev extended attributes"
233+ depends on EXT4DEV_FS
234+ default y
235+ help
236+ Extended attributes are name:value pairs associated with inodes by
237+ the kernel or by users (see the attr(5) manual page, or visit
238+ <http://acl.bestbits.at/> for details).
239+
240+ If unsure, say N.
241+
242+ You need this for POSIX ACL support on ext4dev/ext4.
243+
244+config EXT4DEV_FS_POSIX_ACL
245+ bool "Ext4dev POSIX Access Control Lists"
246+ depends on EXT4DEV_FS_XATTR
247+ select FS_POSIX_ACL
248+ help
249+ POSIX Access Control Lists (ACLs) support permissions for users and
250+ groups beyond the owner/group/world scheme.
251+
252+ To learn more about Access Control Lists, visit the POSIX ACLs for
253+ Linux website <http://acl.bestbits.at/>.
254+
255+ If you don't know what Access Control Lists are, say N
256+
257+config EXT4DEV_FS_SECURITY
258+ bool "Ext4dev Security Labels"
259+ depends on EXT4DEV_FS_XATTR
260+ help
261+ Security labels support alternative access control models
262+ implemented by security modules like SELinux. This option
263+ enables an extended attribute handler for file security
264+ labels in the ext4dev/ext4 filesystem.
265+
266+ If you are not using a security module that requires using
267+ extended attributes for file security labels, say N.
268+
269+config JBD
270+ tristate
271+ help
272+ This is a generic journalling layer for block devices. It is
273+ currently used by the ext3 and OCFS2 file systems, but it could
274+ also be used to add journal support to other file systems or block
275+ devices such as RAID or LVM.
276+
277+ If you are using the ext3 or OCFS2 file systems, you need to
278+ say Y here. If you are not using ext3 OCFS2 then you will probably
279+ want to say N.
280+
281+ To compile this device as a module, choose M here: the module will be
282+ called jbd. If you are compiling ext3 or OCFS2 into the kernel,
283+ you cannot compile this code as a module.
284+
285+config JBD_DEBUG
286+ bool "JBD (ext3) debugging support"
287+ depends on JBD && DEBUG_FS
288+ help
289+ If you are using the ext3 journaled file system (or potentially any
290+ other file system/device using JBD), this option allows you to
291+ enable debugging output while the system is running, in order to
292+ help track down any problems you are having. By default the
293+ debugging output will be turned off.
294+
295+ If you select Y here, then you will be able to turn on debugging
296+ with "echo N > /sys/kernel/debug/jbd/jbd-debug", where N is a
297+ number between 1 and 5, the higher the number, the more debugging
298+ output is generated. To turn debugging off again, do
299+ "echo 0 > /sys/kernel/debug/jbd/jbd-debug".
300+
301+config JBD2
302+ tristate
303+ select CRC32
304+ help
305+ This is a generic journaling layer for block devices that support
306+ both 32-bit and 64-bit block numbers. It is currently used by
307+ the ext4dev/ext4 filesystem, but it could also be used to add
308+ journal support to other file systems or block devices such
309+ as RAID or LVM.
310+
311+ If you are using ext4dev/ext4, you need to say Y here. If you are not
312+ using ext4dev/ext4 then you will probably want to say N.
313+
314+ To compile this device as a module, choose M here. The module will be
315+ called jbd2. If you are compiling ext4dev/ext4 into the kernel,
316+ you cannot compile this code as a module.
317+
318+config JBD2_DEBUG
319+ bool "JBD2 (ext4dev/ext4) debugging support"
320+ depends on JBD2 && DEBUG_FS
321+ help
322+ If you are using the ext4dev/ext4 journaled file system (or
323+ potentially any other filesystem/device using JBD2), this option
324+ allows you to enable debugging output while the system is running,
325+ in order to help track down any problems you are having.
326+ By default, the debugging output will be turned off.
327+
328+ If you select Y here, then you will be able to turn on debugging
329+ with "echo N > /sys/kernel/debug/jbd2/jbd2-debug", where N is a
330+ number between 1 and 5. The higher the number, the more debugging
331+ output is generated. To turn debugging off again, do
332+ "echo 0 > /sys/kernel/debug/jbd2/jbd2-debug".
333+
334+config FS_MBCACHE
335+# Meta block cache for Extended Attributes (ext2/ext3/ext4)
336+ tristate
337+ depends on EXT2_FS_XATTR || EXT3_FS_XATTR || EXT4DEV_FS_XATTR
338+ default y if EXT2_FS=y || EXT3_FS=y || EXT4DEV_FS=y
339+ default m if EXT2_FS=m || EXT3_FS=m || EXT4DEV_FS=m
340+
341+config REISERFS_FS
342+ tristate "Reiserfs support"
343+ help
344+ Stores not just filenames but the files themselves in a balanced
345+ tree. Uses journalling.
346+
347+ Balanced trees are more efficient than traditional file system
348+ architectural foundations.
349+
350+ In general, ReiserFS is as fast as ext2, but is very efficient with
351+ large directories and small files. Additional patches are needed
352+ for NFS and quotas, please see <http://www.namesys.com/> for links.
353+
354+ It is more easily extended to have features currently found in
355+ database and keyword search systems than block allocation based file
356+ systems are. The next version will be so extended, and will support
357+ plugins consistent with our motto ``It takes more than a license to
358+ make source code open.''
359+
360+ Read <http://www.namesys.com/> to learn more about reiserfs.
361+
362+ Sponsored by Threshold Networks, Emusic.com, and Bigstorage.com.
363+
364+ If you like it, you can pay us to add new features to it that you
365+ need, buy a support contract, or pay us to port it to another OS.
366+
367+config REISERFS_CHECK
368+ bool "Enable reiserfs debug mode"
369+ depends on REISERFS_FS
370+ help
371+ If you set this to Y, then ReiserFS will perform every check it can
372+ possibly imagine of its internal consistency throughout its
373+ operation. It will also go substantially slower. More than once we
374+ have forgotten that this was on, and then gone despondent over the
375+ latest benchmarks.:-) Use of this option allows our team to go all
376+ out in checking for consistency when debugging without fear of its
377+ effect on end users. If you are on the verge of sending in a bug
378+ report, say Y and you might get a useful error message. Almost
379+ everyone should say N.
380+
381+config REISERFS_PROC_INFO
382+ bool "Stats in /proc/fs/reiserfs"
383+ depends on REISERFS_FS && PROC_FS
384+ help
385+ Create under /proc/fs/reiserfs a hierarchy of files, displaying
386+ various ReiserFS statistics and internal data at the expense of
387+ making your kernel or module slightly larger (+8 KB). This also
388+ increases the amount of kernel memory required for each mount.
389+ Almost everyone but ReiserFS developers and people fine-tuning
390+ reiserfs or tracing problems should say N.
391+
392+config REISERFS_FS_XATTR
393+ bool "ReiserFS extended attributes"
394+ depends on REISERFS_FS
395+ help
396+ Extended attributes are name:value pairs associated with inodes by
397+ the kernel or by users (see the attr(5) manual page, or visit
398+ <http://acl.bestbits.at/> for details).
399+
400+ If unsure, say N.
401+
402+config REISERFS_FS_POSIX_ACL
403+ bool "ReiserFS POSIX Access Control Lists"
404+ depends on REISERFS_FS_XATTR
405+ select FS_POSIX_ACL
406+ help
407+ Posix Access Control Lists (ACLs) support permissions for users and
408+ groups beyond the owner/group/world scheme.
409+
410+ To learn more about Access Control Lists, visit the Posix ACLs for
411+ Linux website <http://acl.bestbits.at/>.
412+
413+ If you don't know what Access Control Lists are, say N
414+
415+config REISERFS_FS_SECURITY
416+ bool "ReiserFS Security Labels"
417+ depends on REISERFS_FS_XATTR
418+ help
419+ Security labels support alternative access control models
420+ implemented by security modules like SELinux. This option
421+ enables an extended attribute handler for file security
422+ labels in the ReiserFS filesystem.
423+
424+ If you are not using a security module that requires using
425+ extended attributes for file security labels, say N.
426+
427+config JFS_FS
428+ tristate "JFS filesystem support"
429+ select NLS
430+ help
431+ This is a port of IBM's Journaled Filesystem . More information is
432+ available in the file <file:Documentation/filesystems/jfs.txt>.
433+
434+ If you do not intend to use the JFS filesystem, say N.
435+
436+config JFS_POSIX_ACL
437+ bool "JFS POSIX Access Control Lists"
438+ depends on JFS_FS
439+ select FS_POSIX_ACL
440+ help
441+ Posix Access Control Lists (ACLs) support permissions for users and
442+ groups beyond the owner/group/world scheme.
443+
444+ To learn more about Access Control Lists, visit the Posix ACLs for
445+ Linux website <http://acl.bestbits.at/>.
446+
447+ If you don't know what Access Control Lists are, say N
448+
449+config JFS_SECURITY
450+ bool "JFS Security Labels"
451+ depends on JFS_FS
452+ help
453+ Security labels support alternative access control models
454+ implemented by security modules like SELinux. This option
455+ enables an extended attribute handler for file security
456+ labels in the jfs filesystem.
457+
458+ If you are not using a security module that requires using
459+ extended attributes for file security labels, say N.
460+
461+config JFS_DEBUG
462+ bool "JFS debugging"
463+ depends on JFS_FS
464+ help
465+ If you are experiencing any problems with the JFS filesystem, say
466+ Y here. This will result in additional debugging messages to be
467+ written to the system log. Under normal circumstances, this
468+ results in very little overhead.
469+
470+config JFS_STATISTICS
471+ bool "JFS statistics"
472+ depends on JFS_FS
473+ help
474+ Enabling this option will cause statistics from the JFS file system
475+ to be made available to the user in the /proc/fs/jfs/ directory.
476+
477+config FS_POSIX_ACL
478+# Posix ACL utility routines (for now, only ext2/ext3/jfs/reiserfs/nfs4)
479+#
480+# NOTE: you can implement Posix ACLs without these helpers (XFS does).
481+# Never use this symbol for ifdefs.
482+#
483+ bool
484+ default n
485+
486+source "fs/xfs/Kconfig"
487+source "fs/gfs2/Kconfig"
488+
489+config OCFS2_FS
490+ tristate "OCFS2 file system support"
491+ depends on NET && SYSFS
492+ select CONFIGFS_FS
493+ select JBD
494+ select CRC32
495+ help
496+ OCFS2 is a general purpose extent based shared disk cluster file
497+ system with many similarities to ext3. It supports 64 bit inode
498+ numbers, and has automatically extending metadata groups which may
499+ also make it attractive for non-clustered use.
500+
501+ You'll want to install the ocfs2-tools package in order to at least
502+ get "mount.ocfs2".
503+
504+ Project web page: http://oss.oracle.com/projects/ocfs2
505+ Tools web page: http://oss.oracle.com/projects/ocfs2-tools
506+ OCFS2 mailing lists: http://oss.oracle.com/projects/ocfs2/mailman/
507+
508+ For more information on OCFS2, see the file
509+ <file:Documentation/filesystems/ocfs2.txt>.
510+
511+config OCFS2_FS_O2CB
512+ tristate "O2CB Kernelspace Clustering"
513+ depends on OCFS2_FS
514+ default y
515+ help
516+ OCFS2 includes a simple kernelspace clustering package, the OCFS2
517+ Cluster Base. It only requires a very small userspace component
518+ to configure it. This comes with the standard ocfs2-tools package.
519+ O2CB is limited to maintaining a cluster for OCFS2 file systems.
520+ It cannot manage any other cluster applications.
521+
522+ It is always safe to say Y here, as the clustering method is
523+ run-time selectable.
524+
525+config OCFS2_FS_USERSPACE_CLUSTER
526+ tristate "OCFS2 Userspace Clustering"
527+ depends on OCFS2_FS && DLM
528+ default y
529+ help
530+ This option will allow OCFS2 to use userspace clustering services
531+ in conjunction with the DLM in fs/dlm. If you are using a
532+ userspace cluster manager, say Y here.
533+
534+ It is safe to say Y, as the clustering method is run-time
535+ selectable.
536+
537+config OCFS2_FS_STATS
538+ bool "OCFS2 statistics"
539+ depends on OCFS2_FS
540+ default y
541+ help
542+ This option allows some fs statistics to be captured. Enabling
543+ this option may increase the memory consumption.
544+
545+config OCFS2_DEBUG_MASKLOG
546+ bool "OCFS2 logging support"
547+ depends on OCFS2_FS
548+ default y
549+ help
550+ The ocfs2 filesystem has an extensive logging system. The system
551+ allows selection of events to log via files in /sys/o2cb/logmask/.
552+ This option will enlarge your kernel, but it allows debugging of
553+ ocfs2 filesystem issues.
554+
555+config OCFS2_DEBUG_FS
556+ bool "OCFS2 expensive checks"
557+ depends on OCFS2_FS
558+ default n
559+ help
560+ This option will enable expensive consistency checks. Enable
561+ this option for debugging only as it is likely to decrease
562+ performance of the filesystem.
563+
564+endif # BLOCK
565+
566+config DNOTIFY
567+ bool "Dnotify support"
568+ default y
569+ help
570+ Dnotify is a directory-based per-fd file change notification system
571+ that uses signals to communicate events to user-space. There exist
572+ superior alternatives, but some applications may still rely on
573+ dnotify.
574+
575+ If unsure, say Y.
576+
577+config INOTIFY
578+ bool "Inotify file change notification support"
579+ default y
580+ ---help---
581+ Say Y here to enable inotify support. Inotify is a file change
582+ notification system and a replacement for dnotify. Inotify fixes
583+ numerous shortcomings in dnotify and introduces several new features
584+ including multiple file events, one-shot support, and unmount
585+ notification.
586+
587+ For more information, see <file:Documentation/filesystems/inotify.txt>
588+
589+ If unsure, say Y.
590+
591+config INOTIFY_USER
592+ bool "Inotify support for userspace"
593+ depends on INOTIFY
594+ default y
595+ ---help---
596+ Say Y here to enable inotify support for userspace, including the
597+ associated system calls. Inotify allows monitoring of both files and
598+ directories via a single open fd. Events are read from the file
599+ descriptor, which is also select()- and poll()-able.
600+
601+ For more information, see <file:Documentation/filesystems/inotify.txt>
602+
603+ If unsure, say Y.
604+
605+config QUOTA
606+ bool "Quota support"
607+ help
608+ If you say Y here, you will be able to set per user limits for disk
609+ usage (also called disk quotas). Currently, it works for the
610+ ext2, ext3, and reiserfs file system. ext3 also supports journalled
611+ quotas for which you don't need to run quotacheck(8) after an unclean
612+ shutdown.
613+ For further details, read the Quota mini-HOWTO, available from
614+ <http://www.tldp.org/docs.html#howto>, or the documentation provided
615+ with the quota tools. Probably the quota support is only useful for
616+ multi user systems. If unsure, say N.
617+
618+config QUOTA_NETLINK_INTERFACE
619+ bool "Report quota messages through netlink interface"
620+ depends on QUOTA && NET
621+ help
622+ If you say Y here, quota warnings (about exceeding softlimit, reaching
623+ hardlimit, etc.) will be reported through netlink interface. If unsure,
624+ say Y.
625+
626+config PRINT_QUOTA_WARNING
627+ bool "Print quota warnings to console (OBSOLETE)"
628+ depends on QUOTA
629+ default y
630+ help
631+ If you say Y here, quota warnings (about exceeding softlimit, reaching
632+ hardlimit, etc.) will be printed to the process' controlling terminal.
633+ Note that this behavior is currently deprecated and may go away in
634+ future. Please use notification via netlink socket instead.
635+
636+config QFMT_V1
637+ tristate "Old quota format support"
638+ depends on QUOTA
639+ help
640+ This quota format was (is) used by kernels earlier than 2.4.22. If
641+ you have quota working and you don't want to convert to new quota
642+ format say Y here.
643+
644+config QFMT_V2
645+ tristate "Quota format v2 support"
646+ depends on QUOTA
647+ help
648+ This quota format allows using quotas with 32-bit UIDs/GIDs. If you
649+ need this functionality say Y here.
650+
651+config QUOTACTL
652+ bool
653+ depends on XFS_QUOTA || QUOTA
654+ default y
655+
656+config AUTOFS_FS
657+ tristate "Kernel automounter support"
658+ help
659+ The automounter is a tool to automatically mount remote file systems
660+ on demand. This implementation is partially kernel-based to reduce
661+ overhead in the already-mounted case; this is unlike the BSD
662+ automounter (amd), which is a pure user space daemon.
663+
664+ To use the automounter you need the user-space tools from the autofs
665+ package; you can find the location in <file:Documentation/Changes>.
666+ You also want to answer Y to "NFS file system support", below.
667+
668+ If you want to use the newer version of the automounter with more
669+ features, say N here and say Y to "Kernel automounter v4 support",
670+ below.
671+
672+ To compile this support as a module, choose M here: the module will be
673+ called autofs.
674+
675+ If you are not a part of a fairly large, distributed network, you
676+ probably do not need an automounter, and can say N here.
677+
678+config AUTOFS4_FS
679+ tristate "Kernel automounter version 4 support (also supports v3)"
680+ help
681+ The automounter is a tool to automatically mount remote file systems
682+ on demand. This implementation is partially kernel-based to reduce
683+ overhead in the already-mounted case; this is unlike the BSD
684+ automounter (amd), which is a pure user space daemon.
685+
686+ To use the automounter you need the user-space tools from
687+ <ftp://ftp.kernel.org/pub/linux/daemons/autofs/v4/>; you also
688+ want to answer Y to "NFS file system support", below.
689+
690+ To compile this support as a module, choose M here: the module will be
691+ called autofs4. You will need to add "alias autofs autofs4" to your
692+ modules configuration file.
693+
694+ If you are not a part of a fairly large, distributed network or
695+ don't have a laptop which needs to dynamically reconfigure to the
696+ local network, you probably do not need an automounter, and can say
697+ N here.
698+
699+config FUSE_FS
700+ tristate "Filesystem in Userspace support"
701+ help
702+ With FUSE it is possible to implement a fully functional filesystem
703+ in a userspace program.
704+
705+ There's also companion library: libfuse. This library along with
706+ utilities is available from the FUSE homepage:
707+ <http://fuse.sourceforge.net/>
708+
709+ See <file:Documentation/filesystems/fuse.txt> for more information.
710+ See <file:Documentation/Changes> for needed library/utility version.
711+
712+ If you want to develop a userspace FS, or if you want to use
713+ a filesystem based on FUSE, answer Y or M.
714+
715+config GENERIC_ACL
716+ bool
717+ select FS_POSIX_ACL
718+
719+if BLOCK
720+menu "CD-ROM/DVD Filesystems"
721+
722+config ISO9660_FS
723+ tristate "ISO 9660 CDROM file system support"
724+ help
725+ This is the standard file system used on CD-ROMs. It was previously
726+ known as "High Sierra File System" and is called "hsfs" on other
727+ Unix systems. The so-called Rock-Ridge extensions which allow for
728+ long Unix filenames and symbolic links are also supported by this
729+ driver. If you have a CD-ROM drive and want to do more with it than
730+ just listen to audio CDs and watch its LEDs, say Y (and read
731+ <file:Documentation/filesystems/isofs.txt> and the CD-ROM-HOWTO,
732+ available from <http://www.tldp.org/docs.html#howto>), thereby
733+ enlarging your kernel by about 27 KB; otherwise say N.
734+
735+ To compile this file system support as a module, choose M here: the
736+ module will be called isofs.
737+
738+config JOLIET
739+ bool "Microsoft Joliet CDROM extensions"
740+ depends on ISO9660_FS
741+ select NLS
742+ help
743+ Joliet is a Microsoft extension for the ISO 9660 CD-ROM file system
744+ which allows for long filenames in unicode format (unicode is the
745+ new 16 bit character code, successor to ASCII, which encodes the
746+ characters of almost all languages of the world; see
747+ <http://www.unicode.org/> for more information). Say Y here if you
748+ want to be able to read Joliet CD-ROMs under Linux.
749+
750+config ZISOFS
751+ bool "Transparent decompression extension"
752+ depends on ISO9660_FS
753+ select ZLIB_INFLATE
754+ help
755+ This is a Linux-specific extension to RockRidge which lets you store
756+ data in compressed form on a CD-ROM and have it transparently
757+ decompressed when the CD-ROM is accessed. See
758+ <http://www.kernel.org/pub/linux/utils/fs/zisofs/> for the tools
759+ necessary to create such a filesystem. Say Y here if you want to be
760+ able to read such compressed CD-ROMs.
761+
762+config UDF_FS
763+ tristate "UDF file system support"
764+ select CRC_ITU_T
765+ help
766+ This is the new file system used on some CD-ROMs and DVDs. Say Y if
767+ you intend to mount DVD discs or CDRW's written in packet mode, or
768+ if written to by other UDF utilities, such as DirectCD.
769+ Please read <file:Documentation/filesystems/udf.txt>.
770+
771+ To compile this file system support as a module, choose M here: the
772+ module will be called udf.
773+
774+ If unsure, say N.
775+
776+config UDF_NLS
777+ bool
778+ default y
779+ depends on (UDF_FS=m && NLS) || (UDF_FS=y && NLS=y)
780+
781+endmenu
782+endif # BLOCK
783+
784+if BLOCK
785+menu "DOS/FAT/NT Filesystems"
786+
787+config FAT_FS
788+ tristate
789+ select NLS
790+ help
791+ If you want to use one of the FAT-based file systems (the MS-DOS and
792+ VFAT (Windows 95) file systems), then you must say Y or M here
793+ to include FAT support. You will then be able to mount partitions or
794+ diskettes with FAT-based file systems and transparently access the
795+ files on them, i.e. MSDOS files will look and behave just like all
796+ other Unix files.
797+
798+ This FAT support is not a file system in itself, it only provides
799+ the foundation for the other file systems. You will have to say Y or
800+ M to at least one of "MSDOS fs support" or "VFAT fs support" in
801+ order to make use of it.
802+
803+ Another way to read and write MSDOS floppies and hard drive
804+ partitions from within Linux (but not transparently) is with the
805+ mtools ("man mtools") program suite. You don't need to say Y here in
806+ order to do that.
807+
808+ If you need to move large files on floppies between a DOS and a
809+ Linux box, say Y here, mount the floppy under Linux with an MSDOS
810+ file system and use GNU tar's M option. GNU tar is a program
811+ available for Unix and DOS ("man tar" or "info tar").
812+
813+ The FAT support will enlarge your kernel by about 37 KB. If unsure,
814+ say Y.
815+
816+ To compile this as a module, choose M here: the module will be called
817+ fat. Note that if you compile the FAT support as a module, you
818+ cannot compile any of the FAT-based file systems into the kernel
819+ -- they will have to be modules as well.
820+
821+config MSDOS_FS
822+ tristate "MSDOS fs support"
823+ select FAT_FS
824+ help
825+ This allows you to mount MSDOS partitions of your hard drive (unless
826+ they are compressed; to access compressed MSDOS partitions under
827+ Linux, you can either use the DOS emulator DOSEMU, described in the
828+ DOSEMU-HOWTO, available from
829+ <http://www.tldp.org/docs.html#howto>, or try dmsdosfs in
830+ <ftp://ibiblio.org/pub/Linux/system/filesystems/dosfs/>. If you
831+ intend to use dosemu with a non-compressed MSDOS partition, say Y
832+ here) and MSDOS floppies. This means that file access becomes
833+ transparent, i.e. the MSDOS files look and behave just like all
834+ other Unix files.
835+
836+ If you have Windows 95 or Windows NT installed on your MSDOS
837+ partitions, you should use the VFAT file system (say Y to "VFAT fs
838+ support" below), or you will not be able to see the long filenames
839+ generated by Windows 95 / Windows NT.
840+
841+ This option will enlarge your kernel by about 7 KB. If unsure,
842+ answer Y. This will only work if you said Y to "DOS FAT fs support"
843+ as well. To compile this as a module, choose M here: the module will
844+ be called msdos.
845+
846+config VFAT_FS
847+ tristate "VFAT (Windows-95) fs support"
848+ select FAT_FS
849+ help
850+ This option provides support for normal Windows file systems with
851+ long filenames. That includes non-compressed FAT-based file systems
852+ used by Windows 95, Windows 98, Windows NT 4.0, and the Unix
853+ programs from the mtools package.
854+
855+ The VFAT support enlarges your kernel by about 10 KB and it only
856+ works if you said Y to the "DOS FAT fs support" above. Please read
857+ the file <file:Documentation/filesystems/vfat.txt> for details. If
858+ unsure, say Y.
859+
860+ To compile this as a module, choose M here: the module will be called
861+ vfat.
862+
863+config FAT_DEFAULT_CODEPAGE
864+ int "Default codepage for FAT"
865+ depends on MSDOS_FS || VFAT_FS
866+ default 437
867+ help
868+ This option should be set to the codepage of your FAT filesystems.
869+ It can be overridden with the "codepage" mount option.
870+ See <file:Documentation/filesystems/vfat.txt> for more information.
871+
872+config FAT_DEFAULT_IOCHARSET
873+ string "Default iocharset for FAT"
874+ depends on VFAT_FS
875+ default "iso8859-1"
876+ help
877+ Set this to the default input/output character set you'd
878+ like FAT to use. It should probably match the character set
879+ that most of your FAT filesystems use, and can be overridden
880+ with the "iocharset" mount option for FAT filesystems.
881+ Note that "utf8" is not recommended for FAT filesystems.
882+ If unsure, you shouldn't set "utf8" here.
883+ See <file:Documentation/filesystems/vfat.txt> for more information.
884+
885+config NTFS_FS
886+ tristate "NTFS file system support"
887+ select NLS
888+ help
889+ NTFS is the file system of Microsoft Windows NT, 2000, XP and 2003.
890+
891+ Saying Y or M here enables read support. There is partial, but
892+ safe, write support available. For write support you must also
893+ say Y to "NTFS write support" below.
894+
895+ There are also a number of user-space tools available, called
896+ ntfsprogs. These include ntfsundelete and ntfsresize, that work
897+ without NTFS support enabled in the kernel.
898+
899+ This is a rewrite from scratch of Linux NTFS support and replaced
900+ the old NTFS code starting with Linux 2.5.11. A backport to
901+ the Linux 2.4 kernel series is separately available as a patch
902+ from the project web site.
903+
904+ For more information see <file:Documentation/filesystems/ntfs.txt>
905+ and <http://www.linux-ntfs.org/>.
906+
907+ To compile this file system support as a module, choose M here: the
908+ module will be called ntfs.
909+
910+ If you are not using Windows NT, 2000, XP or 2003 in addition to
911+ Linux on your computer it is safe to say N.
912+
913+config NTFS_DEBUG
914+ bool "NTFS debugging support"
915+ depends on NTFS_FS
916+ help
917+ If you are experiencing any problems with the NTFS file system, say
918+ Y here. This will result in additional consistency checks to be
919+ performed by the driver as well as additional debugging messages to
920+ be written to the system log. Note that debugging messages are
921+ disabled by default. To enable them, supply the option debug_msgs=1
922+ at the kernel command line when booting the kernel or as an option
923+ to insmod when loading the ntfs module. Once the driver is active,
924+ you can enable debugging messages by doing (as root):
925+ echo 1 > /proc/sys/fs/ntfs-debug
926+ Replacing the "1" with "0" would disable debug messages.
927+
928+ If you leave debugging messages disabled, this results in little
929+ overhead, but enabling debug messages results in very significant
930+ slowdown of the system.
931+
932+ When reporting bugs, please try to have available a full dump of
933+ debugging messages while the misbehaviour was occurring.
934+
935+config NTFS_RW
936+ bool "NTFS write support"
937+ depends on NTFS_FS
938+ help
939+ This enables the partial, but safe, write support in the NTFS driver.
940+
941+ The only supported operation is overwriting existing files, without
942+ changing the file length. No file or directory creation, deletion or
943+ renaming is possible. Note only non-resident files can be written to
944+ so you may find that some very small files (<500 bytes or so) cannot
945+ be written to.
946+
947+ While we cannot guarantee that it will not damage any data, we have
948+ so far not received a single report where the driver would have
949+ damaged someones data so we assume it is perfectly safe to use.
950+
951+ Note: While write support is safe in this version (a rewrite from
952+ scratch of the NTFS support), it should be noted that the old NTFS
953+ write support, included in Linux 2.5.10 and before (since 1997),
954+ is not safe.
955+
956+ This is currently useful with TopologiLinux. TopologiLinux is run
957+ on top of any DOS/Microsoft Windows system without partitioning your
958+ hard disk. Unlike other Linux distributions TopologiLinux does not
959+ need its own partition. For more information see
960+ <http://topologi-linux.sourceforge.net/>
961+
962+ It is perfectly safe to say N here.
963+
964+endmenu
965+endif # BLOCK
966+
967+menu "Pseudo filesystems"
968+
969+source "fs/proc/Kconfig"
970+
971+config SYSFS
972+ bool "sysfs file system support" if EMBEDDED
973+ default y
974+ help
975+ The sysfs filesystem is a virtual filesystem that the kernel uses to
976+ export internal kernel objects, their attributes, and their
977+ relationships to one another.
978+
979+ Users can use sysfs to ascertain useful information about the running
980+ kernel, such as the devices the kernel has discovered on each bus and
981+ which driver each is bound to. sysfs can also be used to tune devices
982+ and other kernel subsystems.
983+
984+ Some system agents rely on the information in sysfs to operate.
985+ /sbin/hotplug uses device and object attributes in sysfs to assist in
986+ delegating policy decisions, like persistently naming devices.
987+
988+ sysfs is currently used by the block subsystem to mount the root
989+ partition. If sysfs is disabled you must specify the boot device on
990+ the kernel boot command line via its major and minor numbers. For
991+ example, "root=03:01" for /dev/hda1.
992+
993+ Designers of embedded systems may wish to say N here to conserve space.
994+
995+config TMPFS
996+ bool "Virtual memory file system support (former shm fs)"
997+ help
998+ Tmpfs is a file system which keeps all files in virtual memory.
999+
1000+ Everything in tmpfs is temporary in the sense that no files will be
1001+ created on your hard drive. The files live in memory and swap
1002+ space. If you unmount a tmpfs instance, everything stored therein is
1003+ lost.
1004+
1005+ See <file:Documentation/filesystems/tmpfs.txt> for details.
1006+
1007+config TMPFS_POSIX_ACL
1008+ bool "Tmpfs POSIX Access Control Lists"
1009+ depends on TMPFS
1010+ select GENERIC_ACL
1011+ help
1012+ POSIX Access Control Lists (ACLs) support permissions for users and
1013+ groups beyond the owner/group/world scheme.
1014+
1015+ To learn more about Access Control Lists, visit the POSIX ACLs for
1016+ Linux website <http://acl.bestbits.at/>.
1017+
1018+ If you don't know what Access Control Lists are, say N.
1019+
1020+config HUGETLBFS
1021+ bool "HugeTLB file system support"
1022+ depends on X86 || IA64 || PPC64 || SPARC64 || (SUPERH && MMU) || \
1023+ (S390 && 64BIT) || BROKEN
1024+ help
1025+ hugetlbfs is a filesystem backing for HugeTLB pages, based on
1026+ ramfs. For architectures that support it, say Y here and read
1027+ <file:Documentation/vm/hugetlbpage.txt> for details.
1028+
1029+ If unsure, say N.
1030+
1031+config HUGETLB_PAGE
1032+ def_bool HUGETLBFS
1033+
1034+config CONFIGFS_FS
1035+ tristate "Userspace-driven configuration filesystem"
1036+ depends on SYSFS
1037+ help
1038+ configfs is a ram-based filesystem that provides the converse
1039+ of sysfs's functionality. Where sysfs is a filesystem-based
1040+ view of kernel objects, configfs is a filesystem-based manager
1041+ of kernel objects, or config_items.
1042+
1043+ Both sysfs and configfs can and should exist together on the
1044+ same system. One is not a replacement for the other.
1045+
1046+endmenu
1047+
1048+menu "Miscellaneous filesystems"
1049+
1050+config ADFS_FS
1051+ tristate "ADFS file system support (EXPERIMENTAL)"
1052+ depends on BLOCK && EXPERIMENTAL
1053+ help
1054+ The Acorn Disc Filing System is the standard file system of the
1055+ RiscOS operating system which runs on Acorn's ARM-based Risc PC
1056+ systems and the Acorn Archimedes range of machines. If you say Y
1057+ here, Linux will be able to read from ADFS partitions on hard drives
1058+ and from ADFS-formatted floppy discs. If you also want to be able to
1059+ write to those devices, say Y to "ADFS write support" below.
1060+
1061+ The ADFS partition should be the first partition (i.e.,
1062+ /dev/[hs]d?1) on each of your drives. Please read the file
1063+ <file:Documentation/filesystems/adfs.txt> for further details.
1064+
1065+ To compile this code as a module, choose M here: the module will be
1066+ called adfs.
1067+
1068+ If unsure, say N.
1069+
1070+config ADFS_FS_RW
1071+ bool "ADFS write support (DANGEROUS)"
1072+ depends on ADFS_FS
1073+ help
1074+ If you say Y here, you will be able to write to ADFS partitions on
1075+ hard drives and ADFS-formatted floppy disks. This is experimental
1076+ codes, so if you're unsure, say N.
1077+
1078+config AFFS_FS
1079+ tristate "Amiga FFS file system support (EXPERIMENTAL)"
1080+ depends on BLOCK && EXPERIMENTAL
1081+ help
1082+ The Fast File System (FFS) is the common file system used on hard
1083+ disks by Amiga(tm) systems since AmigaOS Version 1.3 (34.20). Say Y
1084+ if you want to be able to read and write files from and to an Amiga
1085+ FFS partition on your hard drive. Amiga floppies however cannot be
1086+ read with this driver due to an incompatibility of the floppy
1087+ controller used in an Amiga and the standard floppy controller in
1088+ PCs and workstations. Read <file:Documentation/filesystems/affs.txt>
1089+ and <file:fs/affs/Changes>.
1090+
1091+ With this driver you can also mount disk files used by Bernd
1092+ Schmidt's Un*X Amiga Emulator
1093+ (<http://www.freiburg.linux.de/~uae/>).
1094+ If you want to do this, you will also need to say Y or M to "Loop
1095+ device support", above.
1096+
1097+ To compile this file system support as a module, choose M here: the
1098+ module will be called affs. If unsure, say N.
1099+
1100+config ECRYPT_FS
1101+ tristate "eCrypt filesystem layer support (EXPERIMENTAL)"
1102+ depends on EXPERIMENTAL && KEYS && CRYPTO && NET
1103+ help
1104+ Encrypted filesystem that operates on the VFS layer. See
1105+ <file:Documentation/filesystems/ecryptfs.txt> to learn more about
1106+ eCryptfs. Userspace components are required and can be
1107+ obtained from <http://ecryptfs.sf.net>.
1108+
1109+ To compile this file system support as a module, choose M here: the
1110+ module will be called ecryptfs.
1111+
1112+config HFS_FS
1113+ tristate "Apple Macintosh file system support (EXPERIMENTAL)"
1114+ depends on BLOCK && EXPERIMENTAL
1115+ select NLS
1116+ help
1117+ If you say Y here, you will be able to mount Macintosh-formatted
1118+ floppy disks and hard drive partitions with full read-write access.
1119+ Please read <file:Documentation/filesystems/hfs.txt> to learn about
1120+ the available mount options.
1121+
1122+ To compile this file system support as a module, choose M here: the
1123+ module will be called hfs.
1124+
1125+config HFSPLUS_FS
1126+ tristate "Apple Extended HFS file system support"
1127+ depends on BLOCK
1128+ select NLS
1129+ select NLS_UTF8
1130+ help
1131+ If you say Y here, you will be able to mount extended format
1132+ Macintosh-formatted hard drive partitions with full read-write access.
1133+
1134+ This file system is often called HFS+ and was introduced with
1135+ MacOS 8. It includes all Mac specific filesystem data such as
1136+ data forks and creator codes, but it also has several UNIX
1137+ style features such as file ownership and permissions.
1138+
1139+config BEFS_FS
1140+ tristate "BeOS file system (BeFS) support (read only) (EXPERIMENTAL)"
1141+ depends on BLOCK && EXPERIMENTAL
1142+ select NLS
1143+ help
1144+ The BeOS File System (BeFS) is the native file system of Be, Inc's
1145+ BeOS. Notable features include support for arbitrary attributes
1146+ on files and directories, and database-like indices on selected
1147+ attributes. (Also note that this driver doesn't make those features
1148+ available at this time). It is a 64 bit filesystem, so it supports
1149+ extremely large volumes and files.
1150+
1151+ If you use this filesystem, you should also say Y to at least one
1152+ of the NLS (native language support) options below.
1153+
1154+ If you don't know what this is about, say N.
1155+
1156+ To compile this as a module, choose M here: the module will be
1157+ called befs.
1158+
1159+config BEFS_DEBUG
1160+ bool "Debug BeFS"
1161+ depends on BEFS_FS
1162+ help
1163+ If you say Y here, you can use the 'debug' mount option to enable
1164+ debugging output from the driver.
1165+
1166+config BFS_FS
1167+ tristate "BFS file system support (EXPERIMENTAL)"
1168+ depends on BLOCK && EXPERIMENTAL
1169+ help
1170+ Boot File System (BFS) is a file system used under SCO UnixWare to
1171+ allow the bootloader access to the kernel image and other important
1172+ files during the boot process. It is usually mounted under /stand
1173+ and corresponds to the slice marked as "STAND" in the UnixWare
1174+ partition. You should say Y if you want to read or write the files
1175+ on your /stand slice from within Linux. You then also need to say Y
1176+ to "UnixWare slices support", below. More information about the BFS
1177+ file system is contained in the file
1178+ <file:Documentation/filesystems/bfs.txt>.
1179+
1180+ If you don't know what this is about, say N.
1181+
1182+ To compile this as a module, choose M here: the module will be called
1183+ bfs. Note that the file system of your root partition (the one
1184+ containing the directory /) cannot be compiled as a module.
1185+
1186+
1187+
1188+config EFS_FS
1189+ tristate "EFS file system support (read only) (EXPERIMENTAL)"
1190+ depends on BLOCK && EXPERIMENTAL
1191+ help
1192+ EFS is an older file system used for non-ISO9660 CD-ROMs and hard
1193+ disk partitions by SGI's IRIX operating system (IRIX 6.0 and newer
1194+ uses the XFS file system for hard disk partitions however).
1195+
1196+ This implementation only offers read-only access. If you don't know
1197+ what all this is about, it's safe to say N. For more information
1198+ about EFS see its home page at <http://aeschi.ch.eu.org/efs/>.
1199+
1200+ To compile the EFS file system support as a module, choose M here: the
1201+ module will be called efs.
1202+
1203+config JFFS2_FS
1204+ tristate "Journalling Flash File System v2 (JFFS2) support"
1205+ select CRC32
1206+ depends on MTD
1207+ help
1208+ JFFS2 is the second generation of the Journalling Flash File System
1209+ for use on diskless embedded devices. It provides improved wear
1210+ levelling, compression and support for hard links. You cannot use
1211+ this on normal block devices, only on 'MTD' devices.
1212+
1213+ Further information on the design and implementation of JFFS2 is
1214+ available at <http://sources.redhat.com/jffs2/>.
1215+
1216+config JFFS2_FS_DEBUG
1217+ int "JFFS2 debugging verbosity (0 = quiet, 2 = noisy)"
1218+ depends on JFFS2_FS
1219+ default "0"
1220+ help
1221+ This controls the amount of debugging messages produced by the JFFS2
1222+ code. Set it to zero for use in production systems. For evaluation,
1223+ testing and debugging, it's advisable to set it to one. This will
1224+ enable a few assertions and will print debugging messages at the
1225+ KERN_DEBUG loglevel, where they won't normally be visible. Level 2
1226+ is unlikely to be useful - it enables extra debugging in certain
1227+ areas which at one point needed debugging, but when the bugs were
1228+ located and fixed, the detailed messages were relegated to level 2.
1229+
1230+ If reporting bugs, please try to have available a full dump of the
1231+ messages at debug level 1 while the misbehaviour was occurring.
1232+
1233+config JFFS2_FS_WRITEBUFFER
1234+ bool "JFFS2 write-buffering support"
1235+ depends on JFFS2_FS
1236+ default y
1237+ help
1238+ This enables the write-buffering support in JFFS2.
1239+
1240+ This functionality is required to support JFFS2 on the following
1241+ types of flash devices:
1242+ - NAND flash
1243+ - NOR flash with transparent ECC
1244+ - DataFlash
1245+
1246+config JFFS2_FS_WBUF_VERIFY
1247+ bool "Verify JFFS2 write-buffer reads"
1248+ depends on JFFS2_FS_WRITEBUFFER
1249+ default n
1250+ help
1251+ This causes JFFS2 to read back every page written through the
1252+ write-buffer, and check for errors.
1253+
1254+config JFFS2_SUMMARY
1255+ bool "JFFS2 summary support (EXPERIMENTAL)"
1256+ depends on JFFS2_FS && EXPERIMENTAL
1257+ default n
1258+ help
1259+ This feature makes it possible to use summary information
1260+ for faster filesystem mount.
1261+
1262+ The summary information can be inserted into a filesystem image
1263+ by the utility 'sumtool'.
1264+
1265+ If unsure, say 'N'.
1266+
1267+config JFFS2_FS_XATTR
1268+ bool "JFFS2 XATTR support (EXPERIMENTAL)"
1269+ depends on JFFS2_FS && EXPERIMENTAL
1270+ default n
1271+ help
1272+ Extended attributes are name:value pairs associated with inodes by
1273+ the kernel or by users (see the attr(5) manual page, or visit
1274+ <http://acl.bestbits.at/> for details).
1275+
1276+ If unsure, say N.
1277+
1278+config JFFS2_FS_POSIX_ACL
1279+ bool "JFFS2 POSIX Access Control Lists"
1280+ depends on JFFS2_FS_XATTR
1281+ default y
1282+ select FS_POSIX_ACL
1283+ help
1284+ Posix Access Control Lists (ACLs) support permissions for users and
1285+ groups beyond the owner/group/world scheme.
1286+
1287+ To learn more about Access Control Lists, visit the Posix ACLs for
1288+ Linux website <http://acl.bestbits.at/>.
1289+
1290+ If you don't know what Access Control Lists are, say N
1291+
1292+config JFFS2_FS_SECURITY
1293+ bool "JFFS2 Security Labels"
1294+ depends on JFFS2_FS_XATTR
1295+ default y
1296+ help
1297+ Security labels support alternative access control models
1298+ implemented by security modules like SELinux. This option
1299+ enables an extended attribute handler for file security
1300+ labels in the jffs2 filesystem.
1301+
1302+ If you are not using a security module that requires using
1303+ extended attributes for file security labels, say N.
1304+
1305+config JFFS2_COMPRESSION_OPTIONS
1306+ bool "Advanced compression options for JFFS2"
1307+ depends on JFFS2_FS
1308+ default n
1309+ help
1310+ Enabling this option allows you to explicitly choose which
1311+ compression modules, if any, are enabled in JFFS2. Removing
1312+ compressors can mean you cannot read existing file systems,
1313+ and enabling experimental compressors can mean that you
1314+ write a file system which cannot be read by a standard kernel.
1315+
1316+ If unsure, you should _definitely_ say 'N'.
1317+
1318+config JFFS2_ZLIB
1319+ bool "JFFS2 ZLIB compression support" if JFFS2_COMPRESSION_OPTIONS
1320+ select ZLIB_INFLATE
1321+ select ZLIB_DEFLATE
1322+ depends on JFFS2_FS
1323+ default y
1324+ help
1325+ Zlib is designed to be a free, general-purpose, legally unencumbered,
1326+ lossless data-compression library for use on virtually any computer
1327+ hardware and operating system. See <http://www.gzip.org/zlib/> for
1328+ further information.
1329+
1330+ Say 'Y' if unsure.
1331+
1332+config JFFS2_LZO
1333+ bool "JFFS2 LZO compression support" if JFFS2_COMPRESSION_OPTIONS
1334+ select LZO_COMPRESS
1335+ select LZO_DECOMPRESS
1336+ depends on JFFS2_FS
1337+ default n
1338+ help
1339+ minilzo-based compression. Generally works better than Zlib.
1340+
1341+ This feature was added in July, 2007. Say 'N' if you need
1342+ compatibility with older bootloaders or kernels.
1343+
1344+config JFFS2_RTIME
1345+ bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS
1346+ depends on JFFS2_FS
1347+ default y
1348+ help
1349+ Rtime does manage to recompress already-compressed data. Say 'Y' if unsure.
1350+
1351+config JFFS2_RUBIN
1352+ bool "JFFS2 RUBIN compression support" if JFFS2_COMPRESSION_OPTIONS
1353+ depends on JFFS2_FS
1354+ default n
1355+ help
1356+ RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure.
1357+
1358+choice
1359+ prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS
1360+ default JFFS2_CMODE_PRIORITY
1361+ depends on JFFS2_FS
1362+ help
1363+ You can set here the default compression mode of JFFS2 from
1364+ the available compression modes. Don't touch if unsure.
1365+
1366+config JFFS2_CMODE_NONE
1367+ bool "no compression"
1368+ help
1369+ Uses no compression.
1370+
1371+config JFFS2_CMODE_PRIORITY
1372+ bool "priority"
1373+ help
1374+ Tries the compressors in a predefined order and chooses the first
1375+ successful one.
1376+
1377+config JFFS2_CMODE_SIZE
1378+ bool "size (EXPERIMENTAL)"
1379+ help
1380+ Tries all compressors and chooses the one which has the smallest
1381+ result.
1382+
1383+config JFFS2_CMODE_FAVOURLZO
1384+ bool "Favour LZO"
1385+ help
1386+ Tries all compressors and chooses the one which has the smallest
1387+ result but gives some preference to LZO (which has faster
1388+ decompression) at the expense of size.
1389+
1390+endchoice
1391+
1392+# UBIFS File system configuration
1393+source "fs/ubifs/Kconfig"
1394+
1395+config CRAMFS
1396+ tristate "Compressed ROM file system support (cramfs)"
1397+ depends on BLOCK
1398+ select ZLIB_INFLATE
1399+ help
1400+ Saying Y here includes support for CramFs (Compressed ROM File
1401+ System). CramFs is designed to be a simple, small, and compressed
1402+ file system for ROM based embedded systems. CramFs is read-only,
1403+ limited to 256MB file systems (with 16MB files), and doesn't support
1404+ 16/32 bits uid/gid, hard links and timestamps.
1405+
1406+ See <file:Documentation/filesystems/cramfs.txt> and
1407+ <file:fs/cramfs/README> for further information.
1408+
1409+ To compile this as a module, choose M here: the module will be called
1410+ cramfs. Note that the root file system (the one containing the
1411+ directory /) cannot be compiled as a module.
1412+
1413+ If unsure, say N.
1414+
1415+config VXFS_FS
1416+ tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
1417+ depends on BLOCK
1418+ help
1419+ FreeVxFS is a file system driver that support the VERITAS VxFS(TM)
1420+ file system format. VERITAS VxFS(TM) is the standard file system
1421+ of SCO UnixWare (and possibly others) and optionally available
1422+ for Sunsoft Solaris, HP-UX and many other operating systems.
1423+ Currently only readonly access is supported.
1424+
1425+ NOTE: the file system type as used by mount(1), mount(2) and
1426+ fstab(5) is 'vxfs' as it describes the file system format, not
1427+ the actual driver.
1428+
1429+ To compile this as a module, choose M here: the module will be
1430+ called freevxfs. If unsure, say N.
1431+
1432+config MINIX_FS
1433+ tristate "Minix file system support"
1434+ depends on BLOCK
1435+ help
1436+ Minix is a simple operating system used in many classes about OS's.
1437+ The minix file system (method to organize files on a hard disk
1438+ partition or a floppy disk) was the original file system for Linux,
1439+ but has been superseded by the second extended file system ext2fs.
1440+ You don't want to use the minix file system on your hard disk
1441+ because of certain built-in restrictions, but it is sometimes found
1442+ on older Linux floppy disks. This option will enlarge your kernel
1443+ by about 28 KB. If unsure, say N.
1444+
1445+ To compile this file system support as a module, choose M here: the
1446+ module will be called minix. Note that the file system of your root
1447+ partition (the one containing the directory /) cannot be compiled as
1448+ a module.
1449+
1450+config OMFS_FS
1451+ tristate "SonicBlue Optimized MPEG File System support"
1452+ depends on BLOCK
1453+ select CRC_ITU_T
1454+ help
1455+ This is the proprietary file system used by the Rio Karma music
1456+ player and ReplayTV DVR. Despite the name, this filesystem is not
1457+ more efficient than a standard FS for MPEG files, in fact likely
1458+ the opposite is true. Say Y if you have either of these devices
1459+ and wish to mount its disk.
1460+
1461+ To compile this file system support as a module, choose M here: the
1462+ module will be called omfs. If unsure, say N.
1463+
1464+config HPFS_FS
1465+ tristate "OS/2 HPFS file system support"
1466+ depends on BLOCK
1467+ help
1468+ OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS
1469+ is the file system used for organizing files on OS/2 hard disk
1470+ partitions. Say Y if you want to be able to read files from and
1471+ write files to an OS/2 HPFS partition on your hard drive. OS/2
1472+ floppies however are in regular MSDOS format, so you don't need this
1473+ option in order to be able to read them. Read
1474+ <file:Documentation/filesystems/hpfs.txt>.
1475+
1476+ To compile this file system support as a module, choose M here: the
1477+ module will be called hpfs. If unsure, say N.
1478+
1479+
1480+config QNX4FS_FS
1481+ tristate "QNX4 file system support (read only)"
1482+ depends on BLOCK
1483+ help
1484+ This is the file system used by the real-time operating systems
1485+ QNX 4 and QNX 6 (the latter is also called QNX RTP).
1486+ Further information is available at <http://www.qnx.com/>.
1487+ Say Y if you intend to mount QNX hard disks or floppies.
1488+ Unless you say Y to "QNX4FS read-write support" below, you will
1489+ only be able to read these file systems.
1490+
1491+ To compile this file system support as a module, choose M here: the
1492+ module will be called qnx4.
1493+
1494+ If you don't know whether you need it, then you don't need it:
1495+ answer N.
1496+
1497+config QNX4FS_RW
1498+ bool "QNX4FS write support (DANGEROUS)"
1499+ depends on QNX4FS_FS && EXPERIMENTAL && BROKEN
1500+ help
1501+ Say Y if you want to test write support for QNX4 file systems.
1502+
1503+ It's currently broken, so for now:
1504+ answer N.
1505+
1506+config ROMFS_FS
1507+ tristate "ROM file system support"
1508+ depends on BLOCK
1509+ ---help---
1510+ This is a very small read-only file system mainly intended for
1511+ initial ram disks of installation disks, but it could be used for
1512+ other read-only media as well. Read
1513+ <file:Documentation/filesystems/romfs.txt> for details.
1514+
1515+ To compile this file system support as a module, choose M here: the
1516+ module will be called romfs. Note that the file system of your
1517+ root partition (the one containing the directory /) cannot be a
1518+ module.
1519+
1520+ If you don't know whether you need it, then you don't need it:
1521+ answer N.
1522+
1523+
1524+config SYSV_FS
1525+ tristate "System V/Xenix/V7/Coherent file system support"
1526+ depends on BLOCK
1527+ help
1528+ SCO, Xenix and Coherent are commercial Unix systems for Intel
1529+ machines, and Version 7 was used on the DEC PDP-11. Saying Y
1530+ here would allow you to read from their floppies and hard disk
1531+ partitions.
1532+
1533+ If you have floppies or hard disk partitions like that, it is likely
1534+ that they contain binaries from those other Unix systems; in order
1535+ to run these binaries, you will want to install linux-abi which is
1536+ a set of kernel modules that lets you run SCO, Xenix, Wyse,
1537+ UnixWare, Dell Unix and System V programs under Linux. It is
1538+ available via FTP (user: ftp) from
1539+ <ftp://ftp.openlinux.org/pub/people/hch/linux-abi/>).
1540+ NOTE: that will work only for binaries from Intel-based systems;
1541+ PDP ones will have to wait until somebody ports Linux to -11 ;-)
1542+
1543+ If you only intend to mount files from some other Unix over the
1544+ network using NFS, you don't need the System V file system support
1545+ (but you need NFS file system support obviously).
1546+
1547+ Note that this option is generally not needed for floppies, since a
1548+ good portable way to transport files and directories between unixes
1549+ (and even other operating systems) is given by the tar program ("man
1550+ tar" or preferably "info tar"). Note also that this option has
1551+ nothing whatsoever to do with the option "System V IPC". Read about
1552+ the System V file system in
1553+ <file:Documentation/filesystems/sysv-fs.txt>.
1554+ Saying Y here will enlarge your kernel by about 27 KB.
1555+
1556+ To compile this as a module, choose M here: the module will be called
1557+ sysv.
1558+
1559+ If you haven't heard about all of this before, it's safe to say N.
1560+
1561+
1562+config UFS_FS
1563+ tristate "UFS file system support (read only)"
1564+ depends on BLOCK
1565+ help
1566+ BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD,
1567+ OpenBSD and NeXTstep) use a file system called UFS. Some System V
1568+ Unixes can create and mount hard disk partitions and diskettes using
1569+ this file system as well. Saying Y here will allow you to read from
1570+ these partitions; if you also want to write to them, say Y to the
1571+ experimental "UFS file system write support", below. Please read the
1572+ file <file:Documentation/filesystems/ufs.txt> for more information.
1573+
1574+ The recently released UFS2 variant (used in FreeBSD 5.x) is
1575+ READ-ONLY supported.
1576+
1577+ Note that this option is generally not needed for floppies, since a
1578+ good portable way to transport files and directories between unixes
1579+ (and even other operating systems) is given by the tar program ("man
1580+ tar" or preferably "info tar").
1581+
1582+ When accessing NeXTstep files, you may need to convert them from the
1583+ NeXT character set to the Latin1 character set; use the program
1584+ recode ("info recode") for this purpose.
1585+
1586+ To compile the UFS file system support as a module, choose M here: the
1587+ module will be called ufs.
1588+
1589+ If you haven't heard about all of this before, it's safe to say N.
1590+
1591+config UFS_FS_WRITE
1592+ bool "UFS file system write support (DANGEROUS)"
1593+ depends on UFS_FS && EXPERIMENTAL
1594+ help
1595+ Say Y here if you want to try writing to UFS partitions. This is
1596+ experimental, so you should back up your UFS partitions beforehand.
1597+
1598+config UFS_DEBUG
1599+ bool "UFS debugging"
1600+ depends on UFS_FS
1601+ help
1602+ If you are experiencing any problems with the UFS filesystem, say
1603+ Y here. This will result in _many_ additional debugging messages to be
1604+ written to the system log.
1605+
1606+endmenu
1607+
1608+menuconfig NETWORK_FILESYSTEMS
1609+ bool "Network File Systems"
1610+ default y
1611+ depends on NET
1612+ ---help---
1613+ Say Y here to get to see options for network filesystems and
1614+ filesystem-related networking code, such as NFS daemon and
1615+ RPCSEC security modules.
1616+
1617+ This option alone does not add any kernel code.
1618+
1619+ If you say N, all options in this submenu will be skipped and
1620+ disabled; if unsure, say Y here.
1621+
1622+if NETWORK_FILESYSTEMS
1623+
1624+config NFS_FS
1625+ tristate "NFS client support"
1626+ depends on INET
1627+ select LOCKD
1628+ select SUNRPC
1629+ select NFS_ACL_SUPPORT if NFS_V3_ACL
1630+ help
1631+ Choose Y here if you want to access files residing on other
1632+ computers using Sun's Network File System protocol. To compile
1633+ this file system support as a module, choose M here: the module
1634+ will be called nfs.
1635+
1636+ To mount file systems exported by NFS servers, you also need to
1637+ install the user space mount.nfs command which can be found in
1638+ the Linux nfs-utils package, available from http://linux-nfs.org/.
1639+ Information about using the mount command is available in the
1640+ mount(8) man page. More detail about the Linux NFS client
1641+ implementation is available via the nfs(5) man page.
1642+
1643+ Below you can choose which versions of the NFS protocol are
1644+ available in the kernel to mount NFS servers. Support for NFS
1645+ version 2 (RFC 1094) is always available when NFS_FS is selected.
1646+
1647+ To configure a system which mounts its root file system via NFS
1648+ at boot time, say Y here, select "Kernel level IP
1649+ autoconfiguration" in the NETWORK menu, and select "Root file
1650+ system on NFS" below. You cannot compile this file system as a
1651+ module in this case.
1652+
1653+ If unsure, say N.
1654+
1655+config NFS_V3
1656+ bool "NFS client support for NFS version 3"
1657+ depends on NFS_FS
1658+ help
1659+ This option enables support for version 3 of the NFS protocol
1660+ (RFC 1813) in the kernel's NFS client.
1661+
1662+ If unsure, say Y.
1663+
1664+config NFS_V3_ACL
1665+ bool "NFS client support for the NFSv3 ACL protocol extension"
1666+ depends on NFS_V3
1667+ help
1668+ Some NFS servers support an auxiliary NFSv3 ACL protocol that
1669+ Sun added to Solaris but never became an official part of the
1670+ NFS version 3 protocol. This protocol extension allows
1671+ applications on NFS clients to manipulate POSIX Access Control
1672+ Lists on files residing on NFS servers. NFS servers enforce
1673+ ACLs on local files whether this protocol is available or not.
1674+
1675+ Choose Y here if your NFS server supports the Solaris NFSv3 ACL
1676+ protocol extension and you want your NFS client to allow
1677+ applications to access and modify ACLs on files on the server.
1678+
1679+ Most NFS servers don't support the Solaris NFSv3 ACL protocol
1680+ extension. You can choose N here or specify the "noacl" mount
1681+ option to prevent your NFS client from trying to use the NFSv3
1682+ ACL protocol.
1683+
1684+ If unsure, say N.
1685+
1686+config NFS_V4
1687+ bool "NFS client support for NFS version 4 (EXPERIMENTAL)"
1688+ depends on NFS_FS && EXPERIMENTAL
1689+ select RPCSEC_GSS_KRB5
1690+ help
1691+ This option enables support for version 4 of the NFS protocol
1692+ (RFC 3530) in the kernel's NFS client.
1693+
1694+ To mount NFS servers using NFSv4, you also need to install user
1695+ space programs which can be found in the Linux nfs-utils package,
1696+ available from http://linux-nfs.org/.
1697+
1698+ If unsure, say N.
1699+
1700+config ROOT_NFS
1701+ bool "Root file system on NFS"
1702+ depends on NFS_FS=y && IP_PNP
1703+ help
1704+ If you want your system to mount its root file system via NFS,
1705+ choose Y here. This is common practice for managing systems
1706+ without local permanent storage. For details, read
1707+ <file:Documentation/filesystems/nfsroot.txt>.
1708+
1709+ Most people say N here.
1710+
1711+config NFSD
1712+ tristate "NFS server support"
1713+ depends on INET
1714+ select LOCKD
1715+ select SUNRPC
1716+ select EXPORTFS
1717+ select NFS_ACL_SUPPORT if NFSD_V2_ACL
1718+ help
1719+ Choose Y here if you want to allow other computers to access
1720+ files residing on this system using Sun's Network File System
1721+ protocol. To compile the NFS server support as a module,
1722+ choose M here: the module will be called nfsd.
1723+
1724+ You may choose to use a user-space NFS server instead, in which
1725+ case you can choose N here.
1726+
1727+ To export local file systems using NFS, you also need to install
1728+ user space programs which can be found in the Linux nfs-utils
1729+ package, available from http://linux-nfs.org/. More detail about
1730+ the Linux NFS server implementation is available via the
1731+ exports(5) man page.
1732+
1733+ Below you can choose which versions of the NFS protocol are
1734+ available to clients mounting the NFS server on this system.
1735+ Support for NFS version 2 (RFC 1094) is always available when
1736+ CONFIG_NFSD is selected.
1737+
1738+ If unsure, say N.
1739+
1740+config NFSD_V2_ACL
1741+ bool
1742+ depends on NFSD
1743+
1744+config NFSD_V3
1745+ bool "NFS server support for NFS version 3"
1746+ depends on NFSD
1747+ help
1748+ This option enables support in your system's NFS server for
1749+ version 3 of the NFS protocol (RFC 1813).
1750+
1751+ If unsure, say Y.
1752+
1753+config NFSD_V3_ACL
1754+ bool "NFS server support for the NFSv3 ACL protocol extension"
1755+ depends on NFSD_V3
1756+ select NFSD_V2_ACL
1757+ help
1758+ Solaris NFS servers support an auxiliary NFSv3 ACL protocol that
1759+ never became an official part of the NFS version 3 protocol.
1760+ This protocol extension allows applications on NFS clients to
1761+ manipulate POSIX Access Control Lists on files residing on NFS
1762+ servers. NFS servers enforce POSIX ACLs on local files whether
1763+ this protocol is available or not.
1764+
1765+ This option enables support in your system's NFS server for the
1766+ NFSv3 ACL protocol extension allowing NFS clients to manipulate
1767+ POSIX ACLs on files exported by your system's NFS server. NFS
1768+ clients which support the Solaris NFSv3 ACL protocol can then
1769+ access and modify ACLs on your NFS server.
1770+
1771+ To store ACLs on your NFS server, you also need to enable ACL-
1772+ related CONFIG options for your local file systems of choice.
1773+
1774+ If unsure, say N.
1775+
1776+config NFSD_V4
1777+ bool "NFS server support for NFS version 4 (EXPERIMENTAL)"
1778+ depends on NFSD && PROC_FS && EXPERIMENTAL
1779+ select NFSD_V3
1780+ select FS_POSIX_ACL
1781+ select RPCSEC_GSS_KRB5
1782+ help
1783+ This option enables support in your system's NFS server for
1784+ version 4 of the NFS protocol (RFC 3530).
1785+
1786+ To export files using NFSv4, you need to install additional user
1787+ space programs which can be found in the Linux nfs-utils package,
1788+ available from http://linux-nfs.org/.
1789+
1790+ If unsure, say N.
1791+
1792+config LOCKD
1793+ tristate
1794+
1795+config LOCKD_V4
1796+ bool
1797+ depends on NFSD_V3 || NFS_V3
1798+ default y
1799+
1800+config EXPORTFS
1801+ tristate
1802+
1803+config NFS_ACL_SUPPORT
1804+ tristate
1805+ select FS_POSIX_ACL
1806+
1807+config NFS_COMMON
1808+ bool
1809+ depends on NFSD || NFS_FS
1810+ default y
1811+
1812+config SUNRPC
1813+ tristate
1814+
1815+config SUNRPC_GSS
1816+ tristate
1817+
1818+config SUNRPC_XPRT_RDMA
1819+ tristate
1820+ depends on SUNRPC && INFINIBAND && EXPERIMENTAL
1821+ default SUNRPC && INFINIBAND
1822+ help
1823+ This option enables an RPC client transport capability that
1824+ allows the NFS client to mount servers via an RDMA-enabled
1825+ transport.
1826+
1827+ To compile RPC client RDMA transport support as a module,
1828+ choose M here: the module will be called xprtrdma.
1829+
1830+ If unsure, say N.
1831+
1832+config RPCSEC_GSS_KRB5
1833+ tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)"
1834+ depends on SUNRPC && EXPERIMENTAL
1835+ select SUNRPC_GSS
1836+ select CRYPTO
1837+ select CRYPTO_MD5
1838+ select CRYPTO_DES
1839+ select CRYPTO_CBC
1840+ help
1841+ Choose Y here to enable Secure RPC using the Kerberos version 5
1842+ GSS-API mechanism (RFC 1964).
1843+
1844+ Secure RPC calls with Kerberos require an auxiliary user-space
1845+ daemon which may be found in the Linux nfs-utils package
1846+ available from http://linux-nfs.org/. In addition, user-space
1847+ Kerberos support should be installed.
1848+
1849+ If unsure, say N.
1850+
1851+config RPCSEC_GSS_SPKM3
1852+ tristate "Secure RPC: SPKM3 mechanism (EXPERIMENTAL)"
1853+ depends on SUNRPC && EXPERIMENTAL
1854+ select SUNRPC_GSS
1855+ select CRYPTO
1856+ select CRYPTO_MD5
1857+ select CRYPTO_DES
1858+ select CRYPTO_CAST5
1859+ select CRYPTO_CBC
1860+ help
1861+ Choose Y here to enable Secure RPC using the SPKM3 public key
1862+ GSS-API mechansim (RFC 2025).
1863+
1864+ Secure RPC calls with SPKM3 require an auxiliary userspace
1865+ daemon which may be found in the Linux nfs-utils package
1866+ available from http://linux-nfs.org/.
1867+
1868+ If unsure, say N.
1869+
1870+config SMB_FS
1871+ tristate "SMB file system support (OBSOLETE, please use CIFS)"
1872+ depends on INET
1873+ select NLS
1874+ help
1875+ SMB (Server Message Block) is the protocol Windows for Workgroups
1876+ (WfW), Windows 95/98, Windows NT and OS/2 Lan Manager use to share
1877+ files and printers over local networks. Saying Y here allows you to
1878+ mount their file systems (often called "shares" in this context) and
1879+ access them just like any other Unix directory. Currently, this
1880+ works only if the Windows machines use TCP/IP as the underlying
1881+ transport protocol, and not NetBEUI. For details, read
1882+ <file:Documentation/filesystems/smbfs.txt> and the SMB-HOWTO,
1883+ available from <http://www.tldp.org/docs.html#howto>.
1884+
1885+ Note: if you just want your box to act as an SMB *server* and make
1886+ files and printing services available to Windows clients (which need
1887+ to have a TCP/IP stack), you don't need to say Y here; you can use
1888+ the program SAMBA (available from <ftp://ftp.samba.org/pub/samba/>)
1889+ for that.
1890+
1891+ General information about how to connect Linux, Windows machines and
1892+ Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.
1893+
1894+ To compile the SMB support as a module, choose M here:
1895+ the module will be called smbfs. Most people say N, however.
1896+
1897+config SMB_NLS_DEFAULT
1898+ bool "Use a default NLS"
1899+ depends on SMB_FS
1900+ help
1901+ Enabling this will make smbfs use nls translations by default. You
1902+ need to specify the local charset (CONFIG_NLS_DEFAULT) in the nls
1903+ settings and you need to give the default nls for the SMB server as
1904+ CONFIG_SMB_NLS_REMOTE.
1905+
1906+ The nls settings can be changed at mount time, if your smbmount
1907+ supports that, using the codepage and iocharset parameters.
1908+
1909+ smbmount from samba 2.2.0 or later supports this.
1910+
1911+config SMB_NLS_REMOTE
1912+ string "Default Remote NLS Option"
1913+ depends on SMB_NLS_DEFAULT
1914+ default "cp437"
1915+ help
1916+ This setting allows you to specify a default value for which
1917+ codepage the server uses. If this field is left blank no
1918+ translations will be done by default. The local codepage/charset
1919+ default to CONFIG_NLS_DEFAULT.
1920+
1921+ The nls settings can be changed at mount time, if your smbmount
1922+ supports that, using the codepage and iocharset parameters.
1923+
1924+ smbmount from samba 2.2.0 or later supports this.
1925+
1926+config CIFS
1927+ tristate "CIFS support (advanced network filesystem, SMBFS successor)"
1928+ depends on INET
1929+ select NLS
1930+ help
1931+ This is the client VFS module for the Common Internet File System
1932+ (CIFS) protocol which is the successor to the Server Message Block
1933+ (SMB) protocol, the native file sharing mechanism for most early
1934+ PC operating systems. The CIFS protocol is fully supported by
1935+ file servers such as Windows 2000 (including Windows 2003, NT 4
1936+ and Windows XP) as well by Samba (which provides excellent CIFS
1937+ server support for Linux and many other operating systems). Limited
1938+ support for OS/2 and Windows ME and similar servers is provided as
1939+ well.
1940+
1941+ The cifs module provides an advanced network file system
1942+ client for mounting to CIFS compliant servers. It includes
1943+ support for DFS (hierarchical name space), secure per-user
1944+ session establishment via Kerberos or NTLM or NTLMv2,
1945+ safe distributed caching (oplock), optional packet
1946+ signing, Unicode and other internationalization improvements.
1947+ If you need to mount to Samba or Windows from this machine, say Y.
1948+
1949+config CIFS_STATS
1950+ bool "CIFS statistics"
1951+ depends on CIFS
1952+ help
1953+ Enabling this option will cause statistics for each server share
1954+ mounted by the cifs client to be displayed in /proc/fs/cifs/Stats
1955+
1956+config CIFS_STATS2
1957+ bool "Extended statistics"
1958+ depends on CIFS_STATS
1959+ help
1960+ Enabling this option will allow more detailed statistics on SMB
1961+ request timing to be displayed in /proc/fs/cifs/DebugData and also
1962+ allow optional logging of slow responses to dmesg (depending on the
1963+ value of /proc/fs/cifs/cifsFYI, see fs/cifs/README for more details).
1964+ These additional statistics may have a minor effect on performance
1965+ and memory utilization.
1966+
1967+ Unless you are a developer or are doing network performance analysis
1968+ or tuning, say N.
1969+
1970+config CIFS_WEAK_PW_HASH
1971+ bool "Support legacy servers which use weaker LANMAN security"
1972+ depends on CIFS
1973+ help
1974+ Modern CIFS servers including Samba and most Windows versions
1975+ (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos)
1976+ security mechanisms. These hash the password more securely
1977+ than the mechanisms used in the older LANMAN version of the
1978+ SMB protocol but LANMAN based authentication is needed to
1979+ establish sessions with some old SMB servers.
1980+
1981+ Enabling this option allows the cifs module to mount to older
1982+ LANMAN based servers such as OS/2 and Windows 95, but such
1983+ mounts may be less secure than mounts using NTLM or more recent
1984+ security mechanisms if you are on a public network. Unless you
1985+ have a need to access old SMB servers (and are on a private
1986+ network) you probably want to say N. Even if this support
1987+ is enabled in the kernel build, LANMAN authentication will not be
1988+ used automatically. At runtime LANMAN mounts are disabled but
1989+ can be set to required (or optional) either in
1990+ /proc/fs/cifs (see fs/cifs/README for more detail) or via an
1991+ option on the mount command. This support is disabled by
1992+ default in order to reduce the possibility of a downgrade
1993+ attack.
1994+
1995+ If unsure, say N.
1996+
1997+config CIFS_XATTR
1998+ bool "CIFS extended attributes"
1999+ depends on CIFS
2000+ help
2001+ Extended attributes are name:value pairs associated with inodes by
2002+ the kernel or by users (see the attr(5) manual page, or visit
2003+ <http://acl.bestbits.at/> for details). CIFS maps the name of
2004+ extended attributes beginning with the user namespace prefix
2005+ to SMB/CIFS EAs. EAs are stored on Windows servers without the
2006+ user namespace prefix, but their names are seen by Linux cifs clients
2007+ prefaced by the user namespace prefix. The system namespace
2008+ (used by some filesystems to store ACLs) is not supported at
2009+ this time.
2010+
2011+ If unsure, say N.
2012+
2013+config CIFS_POSIX
2014+ bool "CIFS POSIX Extensions"
2015+ depends on CIFS_XATTR
2016+ help
2017+ Enabling this option will cause the cifs client to attempt to
2018+ negotiate a newer dialect with servers, such as Samba 3.0.5
2019+ or later, that optionally can handle more POSIX like (rather
2020+ than Windows like) file behavior. It also enables
2021+ support for POSIX ACLs (getfacl and setfacl) to servers
2022+ (such as Samba 3.10 and later) which can negotiate
2023+ CIFS POSIX ACL support. If unsure, say N.
2024+
2025+config CIFS_DEBUG2
2026+ bool "Enable additional CIFS debugging routines"
2027+ depends on CIFS
2028+ help
2029+ Enabling this option adds a few more debugging routines
2030+ to the cifs code which slightly increases the size of
2031+ the cifs module and can cause additional logging of debug
2032+ messages in some error paths, slowing performance. This
2033+ option can be turned off unless you are debugging
2034+ cifs problems. If unsure, say N.
2035+
2036+config CIFS_EXPERIMENTAL
2037+ bool "CIFS Experimental Features (EXPERIMENTAL)"
2038+ depends on CIFS && EXPERIMENTAL
2039+ help
2040+ Enables cifs features under testing. These features are
2041+ experimental and currently include DFS support and directory
2042+ change notification ie fcntl(F_DNOTIFY), as well as the upcall
2043+ mechanism which will be used for Kerberos session negotiation
2044+ and uid remapping. Some of these features also may depend on
2045+ setting a value of 1 to the pseudo-file /proc/fs/cifs/Experimental
2046+ (which is disabled by default). See the file fs/cifs/README
2047+ for more details. If unsure, say N.
2048+
2049+config CIFS_UPCALL
2050+ bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
2051+ depends on CIFS_EXPERIMENTAL
2052+ depends on KEYS
2053+ help
2054+ Enables an upcall mechanism for CIFS which accesses
2055+ userspace helper utilities to provide SPNEGO packaged (RFC 4178)
2056+ Kerberos tickets which are needed to mount to certain secure servers
2057+ (for which more secure Kerberos authentication is required). If
2058+ unsure, say N.
2059+
2060+config CIFS_DFS_UPCALL
2061+ bool "DFS feature support (EXPERIMENTAL)"
2062+ depends on CIFS_EXPERIMENTAL
2063+ depends on KEYS
2064+ help
2065+ Enables an upcall mechanism for CIFS which contacts userspace
2066+ helper utilities to provide server name resolution (host names to
2067+ IP addresses) which is needed for implicit mounts of DFS junction
2068+ points. If unsure, say N.
2069+
2070+config NCP_FS
2071+ tristate "NCP file system support (to mount NetWare volumes)"
2072+ depends on IPX!=n || INET
2073+ help
2074+ NCP (NetWare Core Protocol) is a protocol that runs over IPX and is
2075+ used by Novell NetWare clients to talk to file servers. It is to
2076+ IPX what NFS is to TCP/IP, if that helps. Saying Y here allows you
2077+ to mount NetWare file server volumes and to access them just like
2078+ any other Unix directory. For details, please read the file
2079+ <file:Documentation/filesystems/ncpfs.txt> in the kernel source and
2080+ the IPX-HOWTO from <http://www.tldp.org/docs.html#howto>.
2081+
2082+ You do not have to say Y here if you want your Linux box to act as a
2083+ file *server* for Novell NetWare clients.
2084+
2085+ General information about how to connect Linux, Windows machines and
2086+ Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.
2087+
2088+ To compile this as a module, choose M here: the module will be called
2089+ ncpfs. Say N unless you are connected to a Novell network.
2090+
2091+source "fs/ncpfs/Kconfig"
2092+
2093+config CODA_FS
2094+ tristate "Coda file system support (advanced network fs)"
2095+ depends on INET
2096+ help
2097+ Coda is an advanced network file system, similar to NFS in that it
2098+ enables you to mount file systems of a remote server and access them
2099+ with regular Unix commands as if they were sitting on your hard
2100+ disk. Coda has several advantages over NFS: support for
2101+ disconnected operation (e.g. for laptops), read/write server
2102+ replication, security model for authentication and encryption,
2103+ persistent client caches and write back caching.
2104+
2105+ If you say Y here, your Linux box will be able to act as a Coda
2106+ *client*. You will need user level code as well, both for the
2107+ client and server. Servers are currently user level, i.e. they need
2108+ no kernel support. Please read
2109+ <file:Documentation/filesystems/coda.txt> and check out the Coda
2110+ home page <http://www.coda.cs.cmu.edu/>.
2111+
2112+ To compile the coda client support as a module, choose M here: the
2113+ module will be called coda.
2114+
2115+config AFS_FS
2116+ tristate "Andrew File System support (AFS) (EXPERIMENTAL)"
2117+ depends on INET && EXPERIMENTAL
2118+ select AF_RXRPC
2119+ help
2120+ If you say Y here, you will get an experimental Andrew File System
2121+ driver. It currently only supports unsecured read-only AFS access.
2122+
2123+ See <file:Documentation/filesystems/afs.txt> for more information.
2124+
2125+ If unsure, say N.
2126+
2127+config AFS_DEBUG
2128+ bool "AFS dynamic debugging"
2129+ depends on AFS_FS
2130+ help
2131+ Say Y here to make runtime controllable debugging messages appear.
2132+
2133+ See <file:Documentation/filesystems/afs.txt> for more information.
2134+
2135+ If unsure, say N.
2136+
2137+config 9P_FS
2138+ tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)"
2139+ depends on INET && NET_9P && EXPERIMENTAL
2140+ help
2141+ If you say Y here, you will get experimental support for
2142+ Plan 9 resource sharing via the 9P2000 protocol.
2143+
2144+ See <http://v9fs.sf.net> for more information.
2145+
2146+ If unsure, say N.
2147+
2148+endif # NETWORK_FILESYSTEMS
2149+
2150+if BLOCK
2151+menu "Partition Types"
2152+
2153+source "fs/partitions/Kconfig"
2154+
2155+endmenu
2156+endif
2157+
2158+source "fs/nls/Kconfig"
2159+source "fs/dlm/Kconfig"
2160+
2161+endmenu
2162diff -uNr a/fs/Makefile b/fs/Makefile
2163--- a/fs/Makefile 2008-07-28 19:40:31.000000000 -0700
2164+++ b/fs/Makefile 2008-08-13 16:18:09.000000000 -0700
2165@@ -74,6 +74,7 @@
2166 obj-$(CONFIG_JBD2) += jbd2/
2167 obj-$(CONFIG_EXT2_FS) += ext2/
2168 obj-$(CONFIG_CRAMFS) += cramfs/
2169+obj-$(CONFIG_SQUASHFS) += squashfs/
2170 obj-y += ramfs/
2171 obj-$(CONFIG_HUGETLBFS) += hugetlbfs/
2172 obj-$(CONFIG_CODA_FS) += coda/
2173diff -uNr a/fs/squashfs/block.c b/fs/squashfs/block.c
2174--- a/fs/squashfs/block.c 1969-12-31 16:00:00.000000000 -0800
2175+++ b/fs/squashfs/block.c 2008-08-13 16:14:50.000000000 -0700
2176@@ -0,0 +1,314 @@
2177+/*
2178+ * Squashfs - a compressed read only filesystem for Linux
2179+ *
2180+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
2181+ * Phillip Lougher <phillip@lougher.demon.co.uk>
2182+ *
2183+ * This program is free software; you can redistribute it and/or
2184+ * modify it under the terms of the GNU General Public License
2185+ * as published by the Free Software Foundation; either version 2,
2186+ * or (at your option) any later version.
2187+ *
2188+ * This program is distributed in the hope that it will be useful,
2189+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2190+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2191+ * GNU General Public License for more details.
2192+ *
2193+ * You should have received a copy of the GNU General Public License
2194+ * along with this program; if not, write to the Free Software
2195+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2196+ *
2197+ * block.c
2198+ */
2199+
2200+#include <linux/squashfs_fs.h>
2201+#include <linux/module.h>
2202+#include <linux/zlib.h>
2203+#include <linux/fs.h>
2204+#include <linux/squashfs_fs_sb.h>
2205+#include <linux/squashfs_fs_i.h>
2206+#include <linux/buffer_head.h>
2207+#include <linux/vfs.h>
2208+#include <linux/vmalloc.h>
2209+#include <linux/spinlock.h>
2210+#include <linux/smp_lock.h>
2211+#include <linux/exportfs.h>
2212+
2213+#include "squashfs.h"
2214+static struct buffer_head *get_block_length(struct super_block *s,
2215+ int *cur_index, int *offset, int *c_byte)
2216+{
2217+ struct squashfs_sb_info *msblk = s->s_fs_info;
2218+ unsigned short temp;
2219+ struct buffer_head *bh;
2220+
2221+ if (!(bh = sb_bread(s, *cur_index)))
2222+ goto out;
2223+
2224+ if (msblk->devblksize - *offset == 1) {
2225+ if (msblk->swap)
2226+ ((unsigned char *) &temp)[1] = *((unsigned char *)
2227+ (bh->b_data + *offset));
2228+ else
2229+ ((unsigned char *) &temp)[0] = *((unsigned char *)
2230+ (bh->b_data + *offset));
2231+ brelse(bh);
2232+ if (!(bh = sb_bread(s, ++(*cur_index))))
2233+ goto out;
2234+ if (msblk->swap)
2235+ ((unsigned char *) &temp)[0] = *((unsigned char *)
2236+ bh->b_data);
2237+ else
2238+ ((unsigned char *) &temp)[1] = *((unsigned char *)
2239+ bh->b_data);
2240+ *c_byte = temp;
2241+ *offset = 1;
2242+ } else {
2243+ if (msblk->swap) {
2244+ ((unsigned char *) &temp)[1] = *((unsigned char *)
2245+ (bh->b_data + *offset));
2246+ ((unsigned char *) &temp)[0] = *((unsigned char *)
2247+ (bh->b_data + *offset + 1));
2248+ } else {
2249+ ((unsigned char *) &temp)[0] = *((unsigned char *)
2250+ (bh->b_data + *offset));
2251+ ((unsigned char *) &temp)[1] = *((unsigned char *)
2252+ (bh->b_data + *offset + 1));
2253+ }
2254+ *c_byte = temp;
2255+ *offset += 2;
2256+ }
2257+
2258+ if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) {
2259+ if (*offset == msblk->devblksize) {
2260+ brelse(bh);
2261+ if (!(bh = sb_bread(s, ++(*cur_index))))
2262+ goto out;
2263+ *offset = 0;
2264+ }
2265+ if (*((unsigned char *) (bh->b_data + *offset)) !=
2266+ SQUASHFS_MARKER_BYTE) {
2267+ ERROR("Metadata block marker corrupt @ %x\n",
2268+ *cur_index);
2269+ brelse(bh);
2270+ goto out;
2271+ }
2272+ (*offset)++;
2273+ }
2274+ return bh;
2275+
2276+out:
2277+ return NULL;
2278+}
2279+
2280+
2281+unsigned int squashfs_read_data(struct super_block *s, char *buffer,
2282+ long long index, unsigned int length,
2283+ long long *next_index, int srclength)
2284+{
2285+ struct squashfs_sb_info *msblk = s->s_fs_info;
2286+ struct squashfs_super_block *sblk = &msblk->sblk;
2287+ struct buffer_head **bh;
2288+ unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1);
2289+ unsigned int cur_index = index >> msblk->devblksize_log2;
2290+ int bytes, avail_bytes, b = 0, k = 0;
2291+ unsigned int compressed;
2292+ unsigned int c_byte = length;
2293+
2294+ bh = kmalloc(((sblk->block_size >> msblk->devblksize_log2) + 1) *
2295+ sizeof(struct buffer_head *), GFP_KERNEL);
2296+ if (bh == NULL)
2297+ goto read_failure;
2298+
2299+ if (c_byte) {
2300+ bytes = -offset;
2301+ compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte);
2302+ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
2303+
2304+ TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index,
2305+ compressed ? "" : "un", (unsigned int) c_byte, srclength);
2306+
2307+ if (c_byte > srclength || index < 0 || (index + c_byte) > sblk->bytes_used)
2308+ goto read_failure;
2309+
2310+ for (b = 0; bytes < (int) c_byte; b++, cur_index++) {
2311+ bh[b] = sb_getblk(s, cur_index);
2312+ if (bh[b] == NULL)
2313+ goto block_release;
2314+ bytes += msblk->devblksize;
2315+ }
2316+ ll_rw_block(READ, b, bh);
2317+ } else {
2318+ if (index < 0 || (index + 2) > sblk->bytes_used)
2319+ goto read_failure;
2320+
2321+ bh[0] = get_block_length(s, &cur_index, &offset, &c_byte);
2322+ if (bh[0] == NULL)
2323+ goto read_failure;
2324+ b = 1;
2325+
2326+ bytes = msblk->devblksize - offset;
2327+ compressed = SQUASHFS_COMPRESSED(c_byte);
2328+ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
2329+
2330+ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
2331+ ? "" : "un", (unsigned int) c_byte);
2332+
2333+ if (c_byte > srclength || (index + c_byte) > sblk->bytes_used)
2334+ goto block_release;
2335+
2336+ for (; bytes < c_byte; b++) {
2337+ bh[b] = sb_getblk(s, ++cur_index);
2338+ if (bh[b] == NULL)
2339+ goto block_release;
2340+ bytes += msblk->devblksize;
2341+ }
2342+ ll_rw_block(READ, b - 1, bh + 1);
2343+ }
2344+
2345+ if (compressed) {
2346+ int zlib_err = 0;
2347+
2348+ /*
2349+ * uncompress block
2350+ */
2351+
2352+ mutex_lock(&msblk->read_data_mutex);
2353+
2354+ msblk->stream.next_out = buffer;
2355+ msblk->stream.avail_out = srclength;
2356+
2357+ for (bytes = 0; k < b; k++) {
2358+ avail_bytes = min(c_byte - bytes, msblk->devblksize - offset);
2359+
2360+ wait_on_buffer(bh[k]);
2361+ if (!buffer_uptodate(bh[k]))
2362+ goto release_mutex;
2363+
2364+ msblk->stream.next_in = bh[k]->b_data + offset;
2365+ msblk->stream.avail_in = avail_bytes;
2366+
2367+ if (k == 0) {
2368+ zlib_err = zlib_inflateInit(&msblk->stream);
2369+ if (zlib_err != Z_OK) {
2370+ ERROR("zlib_inflateInit returned unexpected result 0x%x,"
2371+ " srclength %d\n", zlib_err, srclength);
2372+ goto release_mutex;
2373+ }
2374+
2375+ if (avail_bytes == 0) {
2376+ offset = 0;
2377+ brelse(bh[k]);
2378+ continue;
2379+ }
2380+ }
2381+
2382+ zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH);
2383+ if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) {
2384+ ERROR("zlib_inflate returned unexpected result 0x%x,"
2385+ " srclength %d, avail_in %d, avail_out %d\n", zlib_err,
2386+ srclength, msblk->stream.avail_in, msblk->stream.avail_out);
2387+ goto release_mutex;
2388+ }
2389+
2390+ bytes += avail_bytes;
2391+ offset = 0;
2392+ brelse(bh[k]);
2393+ }
2394+
2395+ if (zlib_err != Z_STREAM_END)
2396+ goto release_mutex;
2397+
2398+ zlib_err = zlib_inflateEnd(&msblk->stream);
2399+ if (zlib_err != Z_OK) {
2400+ ERROR("zlib_inflateEnd returned unexpected result 0x%x,"
2401+ " srclength %d\n", zlib_err, srclength);
2402+ goto release_mutex;
2403+ }
2404+ bytes = msblk->stream.total_out;
2405+ mutex_unlock(&msblk->read_data_mutex);
2406+ } else {
2407+ int i;
2408+
2409+ for(i = 0; i < b; i++) {
2410+ wait_on_buffer(bh[i]);
2411+ if (!buffer_uptodate(bh[i]))
2412+ goto block_release;
2413+ }
2414+
2415+ for (bytes = 0; k < b; k++) {
2416+ avail_bytes = min(c_byte - bytes, msblk->devblksize - offset);
2417+
2418+ memcpy(buffer + bytes, bh[k]->b_data + offset, avail_bytes);
2419+ bytes += avail_bytes;
2420+ offset = 0;
2421+ brelse(bh[k]);
2422+ }
2423+ }
2424+
2425+ if (next_index)
2426+ *next_index = index + c_byte + (length ? 0 :
2427+ (SQUASHFS_CHECK_DATA(msblk->sblk.flags) ? 3 : 2));
2428+
2429+ kfree(bh);
2430+ return bytes;
2431+
2432+release_mutex:
2433+ mutex_unlock(&msblk->read_data_mutex);
2434+
2435+block_release:
2436+ for (; k < b; k++)
2437+ brelse(bh[k]);
2438+
2439+read_failure:
2440+ ERROR("sb_bread failed reading block 0x%x\n", cur_index);
2441+ kfree(bh);
2442+ return 0;
2443+}
2444+
2445+
2446+int squashfs_get_cached_block(struct super_block *s, void *buffer,
2447+ long long block, unsigned int offset,
2448+ int length, long long *next_block,
2449+ unsigned int *next_offset)
2450+{
2451+ struct squashfs_sb_info *msblk = s->s_fs_info;
2452+ int bytes, return_length = length;
2453+ struct squashfs_cache_entry *entry;
2454+
2455+ TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset);
2456+
2457+ while (1) {
2458+ entry = squashfs_cache_get(s, msblk->block_cache, block, 0);
2459+ bytes = entry->length - offset;
2460+
2461+ if (entry->error || bytes < 1) {
2462+ return_length = 0;
2463+ goto finish;
2464+ } else if (bytes >= length) {
2465+ if (buffer)
2466+ memcpy(buffer, entry->data + offset, length);
2467+ if (entry->length - offset == length) {
2468+ *next_block = entry->next_index;
2469+ *next_offset = 0;
2470+ } else {
2471+ *next_block = block;
2472+ *next_offset = offset + length;
2473+ }
2474+ goto finish;
2475+ } else {
2476+ if (buffer) {
2477+ memcpy(buffer, entry->data + offset, bytes);
2478+ buffer = (char *) buffer + bytes;
2479+ }
2480+ block = entry->next_index;
2481+ squashfs_cache_put(msblk->block_cache, entry);
2482+ length -= bytes;
2483+ offset = 0;
2484+ }
2485+ }
2486+
2487+finish:
2488+ squashfs_cache_put(msblk->block_cache, entry);
2489+ return return_length;
2490+}
2491diff -uNr a/fs/squashfs/cache.c b/fs/squashfs/cache.c
2492--- a/fs/squashfs/cache.c 1969-12-31 16:00:00.000000000 -0800
2493+++ b/fs/squashfs/cache.c 2008-08-13 16:14:50.000000000 -0700
2494@@ -0,0 +1,189 @@
2495+/*
2496+ * Squashfs - a compressed read only filesystem for Linux
2497+ *
2498+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
2499+ * Phillip Lougher <phillip@lougher.demon.co.uk>
2500+ *
2501+ * This program is free software; you can redistribute it and/or
2502+ * modify it under the terms of the GNU General Public License
2503+ * as published by the Free Software Foundation; either version 2,
2504+ * or (at your option) any later version.
2505+ *
2506+ * This program is distributed in the hope that it will be useful,
2507+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2508+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2509+ * GNU General Public License for more details.
2510+ *
2511+ * You should have received a copy of the GNU General Public License
2512+ * along with this program; if not, write to the Free Software
2513+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2514+ *
2515+ * cache.c
2516+ */
2517+
2518+#include <linux/squashfs_fs.h>
2519+#include <linux/module.h>
2520+#include <linux/zlib.h>
2521+#include <linux/fs.h>
2522+#include <linux/squashfs_fs_sb.h>
2523+#include <linux/squashfs_fs_i.h>
2524+#include <linux/buffer_head.h>
2525+#include <linux/vfs.h>
2526+#include <linux/vmalloc.h>
2527+#include <linux/spinlock.h>
2528+#include <linux/smp_lock.h>
2529+#include <linux/exportfs.h>
2530+
2531+#include "squashfs.h"
2532+struct squashfs_cache_entry *squashfs_cache_get(struct super_block *s,
2533+ struct squashfs_cache *cache, long long block, int length)
2534+{
2535+ int i, n;
2536+ struct squashfs_cache_entry *entry;
2537+
2538+ spin_lock(&cache->lock);
2539+
2540+ while (1) {
2541+ for (i = 0; i < cache->entries && cache->entry[i].block != block; i++);
2542+
2543+ if (i == cache->entries) {
2544+ if (cache->unused_blks == 0) {
2545+ cache->waiting ++;
2546+ spin_unlock(&cache->lock);
2547+ wait_event(cache->wait_queue, cache->unused_blks);
2548+ spin_lock(&cache->lock);
2549+ cache->waiting --;
2550+ continue;
2551+ }
2552+
2553+ i = cache->next_blk;
2554+ for (n = 0; n < cache->entries; n++) {
2555+ if (cache->entry[i].locked == 0)
2556+ break;
2557+ i = (i + 1) % cache->entries;
2558+ }
2559+
2560+ cache->next_blk = (i + 1) % cache->entries;
2561+ entry = &cache->entry[i];
2562+
2563+ cache->unused_blks --;
2564+ entry->block = block;
2565+ entry->locked = 1;
2566+ entry->pending = 1;
2567+ entry->waiting = 0;
2568+ entry->error = 0;
2569+ spin_unlock(&cache->lock);
2570+
2571+ entry->length = squashfs_read_data(s, entry->data,
2572+ block, length, &entry->next_index, cache->block_size);
2573+
2574+ spin_lock(&cache->lock);
2575+
2576+ if (entry->length == 0)
2577+ entry->error = 1;
2578+
2579+ entry->pending = 0;
2580+ spin_unlock(&cache->lock);
2581+ if (entry->waiting)
2582+ wake_up_all(&entry->wait_queue);
2583+ goto out;
2584+ }
2585+
2586+ entry = &cache->entry[i];
2587+ if (entry->locked == 0)
2588+ cache->unused_blks --;
2589+ entry->locked++;
2590+
2591+ if (entry->pending) {
2592+ entry->waiting ++;
2593+ spin_unlock(&cache->lock);
2594+ wait_event(entry->wait_queue, !entry->pending);
2595+ goto out;
2596+ }
2597+
2598+ spin_unlock(&cache->lock);
2599+ goto out;
2600+ }
2601+
2602+out:
2603+ TRACE("Got %s %d, start block %lld, locked %d, error %d\n", i,
2604+ cache->name, entry->block, entry->locked, entry->error);
2605+ if (entry->error)
2606+ ERROR("Unable to read %s cache entry [%llx]\n", cache->name, block);
2607+ return entry;
2608+}
2609+
2610+
2611+void squashfs_cache_put(struct squashfs_cache *cache,
2612+ struct squashfs_cache_entry *entry)
2613+{
2614+ spin_lock(&cache->lock);
2615+ entry->locked --;
2616+ if (entry->locked == 0) {
2617+ cache->unused_blks ++;
2618+ spin_unlock(&cache->lock);
2619+ if (cache->waiting)
2620+ wake_up(&cache->wait_queue);
2621+ } else
2622+ spin_unlock(&cache->lock);
2623+}
2624+
2625+
2626+void squashfs_cache_delete(struct squashfs_cache *cache)
2627+{
2628+ int i;
2629+
2630+ if (cache == NULL)
2631+ return;
2632+
2633+ for (i = 0; i < cache->entries; i++)
2634+ if (cache->entry[i].data) {
2635+ if (cache->use_vmalloc)
2636+ vfree(cache->entry[i].data);
2637+ else
2638+ kfree(cache->entry[i].data);
2639+ }
2640+
2641+ kfree(cache);
2642+}
2643+
2644+
2645+struct squashfs_cache *squashfs_cache_init(char *name, int entries,
2646+ int block_size, int use_vmalloc)
2647+{
2648+ int i;
2649+ struct squashfs_cache *cache = kzalloc(sizeof(struct squashfs_cache) +
2650+ entries * sizeof(struct squashfs_cache_entry), GFP_KERNEL);
2651+ if (cache == NULL) {
2652+ ERROR("Failed to allocate %s cache\n", name);
2653+ goto failed;
2654+ }
2655+
2656+ cache->next_blk = 0;
2657+ cache->unused_blks = entries;
2658+ cache->entries = entries;
2659+ cache->block_size = block_size;
2660+ cache->use_vmalloc = use_vmalloc;
2661+ cache->name = name;
2662+ cache->waiting = 0;
2663+ spin_lock_init(&cache->lock);
2664+ init_waitqueue_head(&cache->wait_queue);
2665+
2666+ for (i = 0; i < entries; i++) {
2667+ init_waitqueue_head(&cache->entry[i].wait_queue);
2668+ cache->entry[i].block = SQUASHFS_INVALID_BLK;
2669+ cache->entry[i].data = use_vmalloc ? vmalloc(block_size) :
2670+ kmalloc(block_size, GFP_KERNEL);
2671+ if (cache->entry[i].data == NULL) {
2672+ ERROR("Failed to allocate %s cache entry\n", name);
2673+ goto cleanup;
2674+ }
2675+ }
2676+
2677+ return cache;
2678+
2679+cleanup:
2680+ squashfs_cache_delete(cache);
2681+failed:
2682+ return NULL;
2683+}
2684diff -uNr a/fs/squashfs/dir.c b/fs/squashfs/dir.c
2685--- a/fs/squashfs/dir.c 1969-12-31 16:00:00.000000000 -0800
2686+++ b/fs/squashfs/dir.c 2008-08-13 16:14:50.000000000 -0700
2687@@ -0,0 +1,216 @@
2688+/*
2689+ * Squashfs - a compressed read only filesystem for Linux
2690+ *
2691+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
2692+ * Phillip Lougher <phillip@lougher.demon.co.uk>
2693+ *
2694+ * This program is free software; you can redistribute it and/or
2695+ * modify it under the terms of the GNU General Public License
2696+ * as published by the Free Software Foundation; either version 2,
2697+ * or (at your option) any later version.
2698+ *
2699+ * This program is distributed in the hope that it will be useful,
2700+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2701+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2702+ * GNU General Public License for more details.
2703+ *
2704+ * You should have received a copy of the GNU General Public License
2705+ * along with this program; if not, write to the Free Software
2706+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2707+ *
2708+ * dir.c
2709+ */
2710+
2711+#include <linux/squashfs_fs.h>
2712+#include <linux/module.h>
2713+#include <linux/zlib.h>
2714+#include <linux/fs.h>
2715+#include <linux/squashfs_fs_sb.h>
2716+#include <linux/squashfs_fs_i.h>
2717+#include <linux/buffer_head.h>
2718+#include <linux/vfs.h>
2719+#include <linux/vmalloc.h>
2720+#include <linux/spinlock.h>
2721+#include <linux/smp_lock.h>
2722+#include <linux/exportfs.h>
2723+
2724+#include "squashfs.h"
2725+
2726+static const unsigned char squashfs_filetype_table[] = {
2727+ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
2728+};
2729+
2730+static int get_dir_index_using_offset(struct super_block *s,
2731+ long long *next_block, unsigned int *next_offset,
2732+ long long index_start, unsigned int index_offset, int i_count,
2733+ long long f_pos)
2734+{
2735+ struct squashfs_sb_info *msblk = s->s_fs_info;
2736+ struct squashfs_super_block *sblk = &msblk->sblk;
2737+ int i, length = 0;
2738+ struct squashfs_dir_index index;
2739+
2740+ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
2741+ i_count, (unsigned int) f_pos);
2742+
2743+ f_pos -= 3;
2744+ if (f_pos == 0)
2745+ goto finish;
2746+
2747+ for (i = 0; i < i_count; i++) {
2748+ if (msblk->swap) {
2749+ struct squashfs_dir_index sindex;
2750+ squashfs_get_cached_block(s, &sindex, index_start, index_offset,
2751+ sizeof(sindex), &index_start, &index_offset);
2752+ SQUASHFS_SWAP_DIR_INDEX(&index, &sindex);
2753+ } else
2754+ squashfs_get_cached_block(s, &index, index_start, index_offset,
2755+ sizeof(index), &index_start, &index_offset);
2756+
2757+ if (index.index > f_pos)
2758+ break;
2759+
2760+ squashfs_get_cached_block(s, NULL, index_start, index_offset,
2761+ index.size + 1, &index_start, &index_offset);
2762+
2763+ length = index.index;
2764+ *next_block = index.start_block + sblk->directory_table_start;
2765+ }
2766+
2767+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
2768+
2769+finish:
2770+ return length + 3;
2771+}
2772+
2773+
2774+static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir)
2775+{
2776+ struct inode *i = file->f_dentry->d_inode;
2777+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
2778+ struct squashfs_super_block *sblk = &msblk->sblk;
2779+ long long next_block = SQUASHFS_I(i)->start_block +
2780+ sblk->directory_table_start;
2781+ int next_offset = SQUASHFS_I(i)->offset, length = 0, dir_count;
2782+ struct squashfs_dir_header dirh;
2783+ struct squashfs_dir_entry *dire;
2784+
2785+ TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset);
2786+
2787+ dire = kmalloc(sizeof(struct squashfs_dir_entry) +
2788+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL);
2789+ if (dire == NULL) {
2790+ ERROR("Failed to allocate squashfs_dir_entry\n");
2791+ goto finish;
2792+ }
2793+
2794+ while(file->f_pos < 3) {
2795+ char *name;
2796+ int size, i_ino;
2797+
2798+ if(file->f_pos == 0) {
2799+ name = ".";
2800+ size = 1;
2801+ i_ino = i->i_ino;
2802+ } else {
2803+ name = "..";
2804+ size = 2;
2805+ i_ino = SQUASHFS_I(i)->u.s2.parent_inode;
2806+ }
2807+ TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n",
2808+ (unsigned int) dirent, name, size, (int)
2809+ file->f_pos, i_ino, squashfs_filetype_table[1]);
2810+
2811+ if (filldir(dirent, name, size, file->f_pos, i_ino,
2812+ squashfs_filetype_table[1]) < 0) {
2813+ TRACE("Filldir returned less than 0\n");
2814+ goto finish;
2815+ }
2816+ file->f_pos += size;
2817+ }
2818+
2819+ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
2820+ SQUASHFS_I(i)->u.s2.directory_index_start,
2821+ SQUASHFS_I(i)->u.s2.directory_index_offset,
2822+ SQUASHFS_I(i)->u.s2.directory_index_count, file->f_pos);
2823+
2824+ while (length < i_size_read(i)) {
2825+ /* read directory header */
2826+ if (msblk->swap) {
2827+ struct squashfs_dir_header sdirh;
2828+
2829+ if (!squashfs_get_cached_block(i->i_sb, &sdirh, next_block,
2830+ next_offset, sizeof(sdirh), &next_block, &next_offset))
2831+ goto failed_read;
2832+
2833+ length += sizeof(sdirh);
2834+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
2835+ } else {
2836+ if (!squashfs_get_cached_block(i->i_sb, &dirh, next_block,
2837+ next_offset, sizeof(dirh), &next_block, &next_offset))
2838+ goto failed_read;
2839+
2840+ length += sizeof(dirh);
2841+ }
2842+
2843+ dir_count = dirh.count + 1;
2844+ while (dir_count--) {
2845+ if (msblk->swap) {
2846+ struct squashfs_dir_entry sdire;
2847+ if (!squashfs_get_cached_block(i->i_sb, &sdire, next_block,
2848+ next_offset, sizeof(sdire), &next_block, &next_offset))
2849+ goto failed_read;
2850+
2851+ length += sizeof(sdire);
2852+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
2853+ } else {
2854+ if (!squashfs_get_cached_block(i->i_sb, dire, next_block,
2855+ next_offset, sizeof(*dire), &next_block, &next_offset))
2856+ goto failed_read;
2857+
2858+ length += sizeof(*dire);
2859+ }
2860+
2861+ if (!squashfs_get_cached_block(i->i_sb, dire->name, next_block,
2862+ next_offset, dire->size + 1, &next_block, &next_offset))
2863+ goto failed_read;
2864+
2865+ length += dire->size + 1;
2866+
2867+ if (file->f_pos >= length)
2868+ continue;
2869+
2870+ dire->name[dire->size + 1] = '\0';
2871+
2872+ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n",
2873+ (unsigned int) dirent, dire->name, dire->size + 1,
2874+ (int) file->f_pos, dirh.start_block, dire->offset,
2875+ dirh.inode_number + dire->inode_number,
2876+ squashfs_filetype_table[dire->type]);
2877+
2878+ if (filldir(dirent, dire->name, dire->size + 1, file->f_pos,
2879+ dirh.inode_number + dire->inode_number,
2880+ squashfs_filetype_table[dire->type]) < 0) {
2881+ TRACE("Filldir returned less than 0\n");
2882+ goto finish;
2883+ }
2884+ file->f_pos = length;
2885+ }
2886+ }
2887+
2888+finish:
2889+ kfree(dire);
2890+ return 0;
2891+
2892+failed_read:
2893+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
2894+ next_offset);
2895+ kfree(dire);
2896+ return 0;
2897+}
2898+
2899+
2900+const struct file_operations squashfs_dir_ops = {
2901+ .read = generic_read_dir,
2902+ .readdir = squashfs_readdir
2903+};
2904diff -uNr a/fs/squashfs/export.c b/fs/squashfs/export.c
2905--- a/fs/squashfs/export.c 1969-12-31 16:00:00.000000000 -0800
2906+++ b/fs/squashfs/export.c 2008-08-13 16:14:50.000000000 -0700
2907@@ -0,0 +1,171 @@
2908+/*
2909+ * Squashfs - a compressed read only filesystem for Linux
2910+ *
2911+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
2912+ * Phillip Lougher <phillip@lougher.demon.co.uk>
2913+ *
2914+ * This program is free software; you can redistribute it and/or
2915+ * modify it under the terms of the GNU General Public License
2916+ * as published by the Free Software Foundation; either version 2,
2917+ * or (at your option) any later version.
2918+ *
2919+ * This program is distributed in the hope that it will be useful,
2920+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2921+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2922+ * GNU General Public License for more details.
2923+ *
2924+ * You should have received a copy of the GNU General Public License
2925+ * along with this program; if not, write to the Free Software
2926+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2927+ *
2928+ * export.c
2929+ */
2930+
2931+#include <linux/squashfs_fs.h>
2932+#include <linux/module.h>
2933+#include <linux/zlib.h>
2934+#include <linux/fs.h>
2935+#include <linux/squashfs_fs_sb.h>
2936+#include <linux/squashfs_fs_i.h>
2937+#include <linux/buffer_head.h>
2938+#include <linux/vfs.h>
2939+#include <linux/vmalloc.h>
2940+#include <linux/spinlock.h>
2941+#include <linux/smp_lock.h>
2942+#include <linux/exportfs.h>
2943+
2944+#include "squashfs.h"
2945+static squashfs_inode_t squashfs_inode_lookup(struct super_block *s, int ino)
2946+{
2947+ struct squashfs_sb_info *msblk = s->s_fs_info;
2948+ long long start = msblk->inode_lookup_table[SQUASHFS_LOOKUP_BLOCK(ino - 1)];
2949+ int offset = SQUASHFS_LOOKUP_BLOCK_OFFSET(ino - 1);
2950+ squashfs_inode_t inode;
2951+
2952+ TRACE("Entered squashfs_inode_lookup, inode_number = %d\n", ino);
2953+
2954+ if (msblk->swap) {
2955+ squashfs_inode_t sinode;
2956+
2957+ if (!squashfs_get_cached_block(s, &sinode, start, offset,
2958+ sizeof(sinode), &start, &offset))
2959+ goto out;
2960+ SQUASHFS_SWAP_INODE_T((&inode), &sinode);
2961+ } else if (!squashfs_get_cached_block(s, &inode, start, offset,
2962+ sizeof(inode), &start, &offset))
2963+ goto out;
2964+
2965+ TRACE("squashfs_inode_lookup, inode = 0x%llx\n", inode);
2966+
2967+ return inode;
2968+
2969+out:
2970+ return SQUASHFS_INVALID_BLK;
2971+}
2972+
2973+
2974+static struct dentry *squashfs_export_iget(struct super_block *s,
2975+ unsigned int inode_number)
2976+{
2977+ squashfs_inode_t inode;
2978+ struct inode *i;
2979+ struct dentry *dentry;
2980+
2981+ TRACE("Entered squashfs_export_iget\n");
2982+
2983+ inode = squashfs_inode_lookup(s, inode_number);
2984+ if(inode == SQUASHFS_INVALID_BLK) {
2985+ dentry = ERR_PTR(-ENOENT);
2986+ goto failure;
2987+ }
2988+
2989+ i = squashfs_iget(s, inode, inode_number);
2990+ if(i == NULL) {
2991+ dentry = ERR_PTR(-EACCES);
2992+ goto failure;
2993+ }
2994+
2995+ dentry = d_alloc_anon(i);
2996+ if (dentry == NULL) {
2997+ iput(i);
2998+ dentry = ERR_PTR(-ENOMEM);
2999+ }
3000+
3001+failure:
3002+ return dentry;
3003+}
3004+
3005+
3006+static struct dentry *squashfs_fh_to_dentry(struct super_block *s,
3007+ struct fid *fid, int fh_len, int fh_type)
3008+{
3009+ if((fh_type != FILEID_INO32_GEN && fh_type != FILEID_INO32_GEN_PARENT) ||
3010+ fh_len < 2)
3011+ return NULL;
3012+
3013+ return squashfs_export_iget(s, fid->i32.ino);
3014+}
3015+
3016+
3017+static struct dentry *squashfs_fh_to_parent(struct super_block *s,
3018+ struct fid *fid, int fh_len, int fh_type)
3019+{
3020+ if(fh_type != FILEID_INO32_GEN_PARENT || fh_len < 4)
3021+ return NULL;
3022+
3023+ return squashfs_export_iget(s, fid->i32.parent_ino);
3024+}
3025+
3026+
3027+static struct dentry *squashfs_get_parent(struct dentry *child)
3028+{
3029+ struct inode *i = child->d_inode;
3030+
3031+ TRACE("Entered squashfs_get_parent\n");
3032+
3033+ return squashfs_export_iget(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode);
3034+}
3035+
3036+
3037+int read_inode_lookup_table(struct super_block *s)
3038+{
3039+ struct squashfs_sb_info *msblk = s->s_fs_info;
3040+ struct squashfs_super_block *sblk = &msblk->sblk;
3041+ unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(sblk->inodes);
3042+
3043+ TRACE("In read_inode_lookup_table, length %d\n", length);
3044+
3045+ /* Allocate inode lookup table */
3046+ msblk->inode_lookup_table = kmalloc(length, GFP_KERNEL);
3047+ if (msblk->inode_lookup_table == NULL) {
3048+ ERROR("Failed to allocate inode lookup table\n");
3049+ return 0;
3050+ }
3051+
3052+ if (!squashfs_read_data(s, (char *) msblk->inode_lookup_table,
3053+ sblk->lookup_table_start, length |
3054+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) {
3055+ ERROR("unable to read inode lookup table\n");
3056+ return 0;
3057+ }
3058+
3059+ if (msblk->swap) {
3060+ int i;
3061+ long long block;
3062+
3063+ for (i = 0; i < SQUASHFS_LOOKUP_BLOCKS(sblk->inodes); i++) {
3064+ SQUASHFS_SWAP_LOOKUP_BLOCKS((&block),
3065+ &msblk->inode_lookup_table[i], 1);
3066+ msblk->inode_lookup_table[i] = block;
3067+ }
3068+ }
3069+
3070+ return 1;
3071+}
3072+
3073+
3074+const struct export_operations squashfs_export_ops = {
3075+ .fh_to_dentry = squashfs_fh_to_dentry,
3076+ .fh_to_parent = squashfs_fh_to_parent,
3077+ .get_parent = squashfs_get_parent
3078+};
3079diff -uNr a/fs/squashfs/file.c b/fs/squashfs/file.c
3080--- a/fs/squashfs/file.c 1969-12-31 16:00:00.000000000 -0800
3081+++ b/fs/squashfs/file.c 2008-08-13 16:14:50.000000000 -0700
3082@@ -0,0 +1,430 @@
3083+/*
3084+ * Squashfs - a compressed read only filesystem for Linux
3085+ *
3086+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3087+ * Phillip Lougher <phillip@lougher.demon.co.uk>
3088+ *
3089+ * This program is free software; you can redistribute it and/or
3090+ * modify it under the terms of the GNU General Public License
3091+ * as published by the Free Software Foundation; either version 2,
3092+ * or (at your option) any later version.
3093+ *
3094+ * This program is distributed in the hope that it will be useful,
3095+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3096+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3097+ * GNU General Public License for more details.
3098+ *
3099+ * You should have received a copy of the GNU General Public License
3100+ * along with this program; if not, write to the Free Software
3101+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3102+ *
3103+ * file.c
3104+ */
3105+
3106+#include <linux/squashfs_fs.h>
3107+#include <linux/module.h>
3108+#include <linux/zlib.h>
3109+#include <linux/fs.h>
3110+#include <linux/squashfs_fs_sb.h>
3111+#include <linux/squashfs_fs_i.h>
3112+#include <linux/buffer_head.h>
3113+#include <linux/vfs.h>
3114+#include <linux/vmalloc.h>
3115+#include <linux/spinlock.h>
3116+#include <linux/smp_lock.h>
3117+#include <linux/exportfs.h>
3118+
3119+#include "squashfs.h"
3120+
3121+static struct meta_index *locate_meta_index(struct inode *inode, int index, int offset)
3122+{
3123+ struct meta_index *meta = NULL;
3124+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
3125+ int i;
3126+
3127+ mutex_lock(&msblk->meta_index_mutex);
3128+
3129+ TRACE("locate_meta_index: index %d, offset %d\n", index, offset);
3130+
3131+ if (msblk->meta_index == NULL)
3132+ goto not_allocated;
3133+
3134+ for (i = 0; i < SQUASHFS_META_NUMBER; i ++) {
3135+ if (msblk->meta_index[i].inode_number == inode->i_ino &&
3136+ msblk->meta_index[i].offset >= offset &&
3137+ msblk->meta_index[i].offset <= index &&
3138+ msblk->meta_index[i].locked == 0) {
3139+ TRACE("locate_meta_index: entry %d, offset %d\n", i,
3140+ msblk->meta_index[i].offset);
3141+ meta = &msblk->meta_index[i];
3142+ offset = meta->offset;
3143+ }
3144+ }
3145+
3146+ if (meta)
3147+ meta->locked = 1;
3148+
3149+not_allocated:
3150+ mutex_unlock(&msblk->meta_index_mutex);
3151+
3152+ return meta;
3153+}
3154+
3155+
3156+static struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip)
3157+{
3158+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
3159+ struct meta_index *meta = NULL;
3160+ int i;
3161+
3162+ mutex_lock(&msblk->meta_index_mutex);
3163+
3164+ TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip);
3165+
3166+ if (msblk->meta_index == NULL) {
3167+ msblk->meta_index = kmalloc(sizeof(struct meta_index) *
3168+ SQUASHFS_META_NUMBER, GFP_KERNEL);
3169+ if (msblk->meta_index == NULL) {
3170+ ERROR("Failed to allocate meta_index\n");
3171+ goto failed;
3172+ }
3173+ for (i = 0; i < SQUASHFS_META_NUMBER; i++) {
3174+ msblk->meta_index[i].inode_number = 0;
3175+ msblk->meta_index[i].locked = 0;
3176+ }
3177+ msblk->next_meta_index = 0;
3178+ }
3179+
3180+ for (i = SQUASHFS_META_NUMBER; i &&
3181+ msblk->meta_index[msblk->next_meta_index].locked; i --)
3182+ msblk->next_meta_index = (msblk->next_meta_index + 1) %
3183+ SQUASHFS_META_NUMBER;
3184+
3185+ if (i == 0) {
3186+ TRACE("empty_meta_index: failed!\n");
3187+ goto failed;
3188+ }
3189+
3190+ TRACE("empty_meta_index: returned meta entry %d, %p\n",
3191+ msblk->next_meta_index,
3192+ &msblk->meta_index[msblk->next_meta_index]);
3193+
3194+ meta = &msblk->meta_index[msblk->next_meta_index];
3195+ msblk->next_meta_index = (msblk->next_meta_index + 1) %
3196+ SQUASHFS_META_NUMBER;
3197+
3198+ meta->inode_number = inode->i_ino;
3199+ meta->offset = offset;
3200+ meta->skip = skip;
3201+ meta->entries = 0;
3202+ meta->locked = 1;
3203+
3204+failed:
3205+ mutex_unlock(&msblk->meta_index_mutex);
3206+ return meta;
3207+}
3208+
3209+
3210+static void release_meta_index(struct inode *inode, struct meta_index *meta)
3211+{
3212+ meta->locked = 0;
3213+ smp_mb();
3214+}
3215+
3216+
3217+static int read_block_index(struct super_block *s, int blocks, char *block_list,
3218+ long long *start_block, int *offset)
3219+{
3220+ struct squashfs_sb_info *msblk = s->s_fs_info;
3221+ unsigned int *block_listp;
3222+ int block = 0;
3223+
3224+ if (msblk->swap) {
3225+ char sblock_list[blocks << 2];
3226+
3227+ if (!squashfs_get_cached_block(s, sblock_list, *start_block,
3228+ *offset, blocks << 2, start_block, offset)) {
3229+ ERROR("Fail reading block list [%llx:%x]\n", *start_block, *offset);
3230+ goto failure;
3231+ }
3232+ SQUASHFS_SWAP_INTS(((unsigned int *)block_list),
3233+ ((unsigned int *)sblock_list), blocks);
3234+ } else {
3235+ if (!squashfs_get_cached_block(s, block_list, *start_block,
3236+ *offset, blocks << 2, start_block, offset)) {
3237+ ERROR("Fail reading block list [%llx:%x]\n", *start_block, *offset);
3238+ goto failure;
3239+ }
3240+ }
3241+
3242+ for (block_listp = (unsigned int *) block_list; blocks;
3243+ block_listp++, blocks --)
3244+ block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp);
3245+
3246+ return block;
3247+
3248+failure:
3249+ return -1;
3250+}
3251+
3252+
3253+#define SIZE 256
3254+
3255+static inline int calculate_skip(int blocks) {
3256+ int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES);
3257+ return skip >= 7 ? 7 : skip + 1;
3258+}
3259+
3260+
3261+static int get_meta_index(struct inode *inode, int index,
3262+ long long *index_block, int *index_offset,
3263+ long long *data_block, char *block_list)
3264+{
3265+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
3266+ struct squashfs_super_block *sblk = &msblk->sblk;
3267+ int skip = calculate_skip(i_size_read(inode) >> sblk->block_log);
3268+ int offset = 0;
3269+ struct meta_index *meta;
3270+ struct meta_entry *meta_entry;
3271+ long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start;
3272+ int cur_offset = SQUASHFS_I(inode)->offset;
3273+ long long cur_data_block = SQUASHFS_I(inode)->start_block;
3274+ int i;
3275+
3276+ index /= SQUASHFS_META_INDEXES * skip;
3277+
3278+ while (offset < index) {
3279+ meta = locate_meta_index(inode, index, offset + 1);
3280+
3281+ if (meta == NULL) {
3282+ meta = empty_meta_index(inode, offset + 1, skip);
3283+ if (meta == NULL)
3284+ goto all_done;
3285+ } else {
3286+ if(meta->entries == 0)
3287+ goto failed;
3288+ /* XXX */
3289+ offset = index < meta->offset + meta->entries ? index :
3290+ meta->offset + meta->entries - 1;
3291+ /* XXX */
3292+ meta_entry = &meta->meta_entry[offset - meta->offset];
3293+ cur_index_block = meta_entry->index_block + sblk->inode_table_start;
3294+ cur_offset = meta_entry->offset;
3295+ cur_data_block = meta_entry->data_block;
3296+ TRACE("get_meta_index: offset %d, meta->offset %d, "
3297+ "meta->entries %d\n", offset, meta->offset, meta->entries);
3298+ TRACE("get_meta_index: index_block 0x%llx, offset 0x%x"
3299+ " data_block 0x%llx\n", cur_index_block,
3300+ cur_offset, cur_data_block);
3301+ }
3302+
3303+ for (i = meta->offset + meta->entries; i <= index &&
3304+ i < meta->offset + SQUASHFS_META_ENTRIES; i++) {
3305+ int blocks = skip * SQUASHFS_META_INDEXES;
3306+
3307+ while (blocks) {
3308+ int block = blocks > (SIZE >> 2) ? (SIZE >> 2) : blocks;
3309+ int res = read_block_index(inode->i_sb, block, block_list,
3310+ &cur_index_block, &cur_offset);
3311+
3312+ if (res == -1)
3313+ goto failed;
3314+
3315+ cur_data_block += res;
3316+ blocks -= block;
3317+ }
3318+
3319+ meta_entry = &meta->meta_entry[i - meta->offset];
3320+ meta_entry->index_block = cur_index_block - sblk->inode_table_start;
3321+ meta_entry->offset = cur_offset;
3322+ meta_entry->data_block = cur_data_block;
3323+ meta->entries ++;
3324+ offset ++;
3325+ }
3326+
3327+ TRACE("get_meta_index: meta->offset %d, meta->entries %d\n",
3328+ meta->offset, meta->entries);
3329+
3330+ release_meta_index(inode, meta);
3331+ }
3332+
3333+all_done:
3334+ *index_block = cur_index_block;
3335+ *index_offset = cur_offset;
3336+ *data_block = cur_data_block;
3337+
3338+ return offset * SQUASHFS_META_INDEXES * skip;
3339+
3340+failed:
3341+ release_meta_index(inode, meta);
3342+ return -1;
3343+}
3344+
3345+
3346+long long read_blocklist(struct inode *inode, int index,
3347+ int readahead_blks, char *block_list,
3348+ unsigned short **block_p, unsigned int *bsize)
3349+{
3350+ long long block_ptr;
3351+ int offset;
3352+ long long block;
3353+ int res = get_meta_index(inode, index, &block_ptr, &offset, &block,
3354+ block_list);
3355+
3356+ TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset"
3357+ " 0x%x, block 0x%llx\n", res, index, block_ptr, offset, block);
3358+
3359+ if(res == -1)
3360+ goto failure;
3361+
3362+ index -= res;
3363+
3364+ while (index) {
3365+ int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index;
3366+ int res = read_block_index(inode->i_sb, blocks, block_list,
3367+ &block_ptr, &offset);
3368+ if (res == -1)
3369+ goto failure;
3370+ block += res;
3371+ index -= blocks;
3372+ }
3373+
3374+ if (read_block_index(inode->i_sb, 1, block_list, &block_ptr, &offset) == -1)
3375+ goto failure;
3376+ *bsize = *((unsigned int *) block_list);
3377+
3378+ return block;
3379+
3380+failure:
3381+ return 0;
3382+}
3383+
3384+
3385+static int squashfs_readpage(struct file *file, struct page *page)
3386+{
3387+ struct inode *inode = page->mapping->host;
3388+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
3389+ struct squashfs_super_block *sblk = &msblk->sblk;
3390+ unsigned char *block_list = NULL;
3391+ long long block;
3392+ unsigned int bsize, i;
3393+ int bytes;
3394+ int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT);
3395+ void *pageaddr;
3396+ struct squashfs_cache_entry *fragment = NULL;
3397+ char *data_ptr = msblk->read_page;
3398+
3399+ int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1;
3400+ int start_index = page->index & ~mask;
3401+ int end_index = start_index | mask;
3402+ int file_end = i_size_read(inode) >> sblk->block_log;
3403+ int sparse = 0;
3404+
3405+ TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
3406+ page->index, SQUASHFS_I(inode)->start_block);
3407+
3408+ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
3409+ PAGE_CACHE_SHIFT))
3410+ goto out;
3411+
3412+ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
3413+ || index < file_end) {
3414+ block_list = kmalloc(SIZE, GFP_KERNEL);
3415+ if (block_list == NULL) {
3416+ ERROR("Failed to allocate block_list\n");
3417+ goto error_out;
3418+ }
3419+
3420+ block = (msblk->read_blocklist)(inode, index, 1, block_list, NULL, &bsize);
3421+ if (block == 0)
3422+ goto error_out;
3423+
3424+ if (bsize == 0) { /* hole */
3425+ bytes = index == file_end ?
3426+ (i_size_read(inode) & (sblk->block_size - 1)) : sblk->block_size;
3427+ sparse = 1;
3428+ } else {
3429+ mutex_lock(&msblk->read_page_mutex);
3430+
3431+ bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block,
3432+ bsize, NULL, sblk->block_size);
3433+
3434+ if (bytes == 0) {
3435+ ERROR("Unable to read page, block %llx, size %x\n", block, bsize);
3436+ mutex_unlock(&msblk->read_page_mutex);
3437+ goto error_out;
3438+ }
3439+ }
3440+ } else {
3441+ fragment = get_cached_fragment(inode->i_sb,
3442+ SQUASHFS_I(inode)-> u.s1.fragment_start_block,
3443+ SQUASHFS_I(inode)->u.s1.fragment_size);
3444+
3445+ if (fragment->error) {
3446+ ERROR("Unable to read page, block %llx, size %x\n",
3447+ SQUASHFS_I(inode)->u.s1.fragment_start_block,
3448+ (int) SQUASHFS_I(inode)->u.s1.fragment_size);
3449+ release_cached_fragment(msblk, fragment);
3450+ goto error_out;
3451+ }
3452+ bytes = i_size_read(inode) & (sblk->block_size - 1);
3453+ data_ptr = fragment->data + SQUASHFS_I(inode)->u.s1.fragment_offset;
3454+ }
3455+
3456+ for (i = start_index; i <= end_index && bytes > 0; i++,
3457+ bytes -= PAGE_CACHE_SIZE, data_ptr += PAGE_CACHE_SIZE) {
3458+ struct page *push_page;
3459+ int avail = sparse ? 0 : min_t(unsigned int, bytes, PAGE_CACHE_SIZE);
3460+
3461+ TRACE("bytes %d, i %d, available_bytes %d\n", bytes, i, avail);
3462+
3463+ push_page = (i == page->index) ? page :
3464+ grab_cache_page_nowait(page->mapping, i);
3465+
3466+ if (!push_page)
3467+ continue;
3468+
3469+ if (PageUptodate(push_page))
3470+ goto skip_page;
3471+
3472+ pageaddr = kmap_atomic(push_page, KM_USER0);
3473+ memcpy(pageaddr, data_ptr, avail);
3474+ memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail);
3475+ kunmap_atomic(pageaddr, KM_USER0);
3476+ flush_dcache_page(push_page);
3477+ SetPageUptodate(push_page);
3478+skip_page:
3479+ unlock_page(push_page);
3480+ if(i != page->index)
3481+ page_cache_release(push_page);
3482+ }
3483+
3484+ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
3485+ || index < file_end) {
3486+ if (!sparse)
3487+ mutex_unlock(&msblk->read_page_mutex);
3488+ kfree(block_list);
3489+ } else
3490+ release_cached_fragment(msblk, fragment);
3491+
3492+ return 0;
3493+
3494+error_out:
3495+ SetPageError(page);
3496+out:
3497+ pageaddr = kmap_atomic(page, KM_USER0);
3498+ memset(pageaddr, 0, PAGE_CACHE_SIZE);
3499+ kunmap_atomic(pageaddr, KM_USER0);
3500+ flush_dcache_page(page);
3501+ if (!PageError(page))
3502+ SetPageUptodate(page);
3503+ unlock_page(page);
3504+
3505+ kfree(block_list);
3506+ return 0;
3507+}
3508+
3509+
3510+const struct address_space_operations squashfs_aops = {
3511+ .readpage = squashfs_readpage
3512+};
3513diff -uNr a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c
3514--- a/fs/squashfs/fragment.c 1969-12-31 16:00:00.000000000 -0800
3515+++ b/fs/squashfs/fragment.c 2008-08-13 16:14:50.000000000 -0700
3516@@ -0,0 +1,122 @@
3517+/*
3518+ * Squashfs - a compressed read only filesystem for Linux
3519+ *
3520+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3521+ * Phillip Lougher <phillip@lougher.demon.co.uk>
3522+ *
3523+ * This program is free software; you can redistribute it and/or
3524+ * modify it under the terms of the GNU General Public License
3525+ * as published by the Free Software Foundation; either version 2,
3526+ * or (at your option) any later version.
3527+ *
3528+ * This program is distributed in the hope that it will be useful,
3529+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3530+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3531+ * GNU General Public License for more details.
3532+ *
3533+ * You should have received a copy of the GNU General Public License
3534+ * along with this program; if not, write to the Free Software
3535+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3536+ *
3537+ * fragment.c
3538+ */
3539+
3540+#include <linux/squashfs_fs.h>
3541+#include <linux/module.h>
3542+#include <linux/zlib.h>
3543+#include <linux/fs.h>
3544+#include <linux/squashfs_fs_sb.h>
3545+#include <linux/squashfs_fs_i.h>
3546+#include <linux/buffer_head.h>
3547+#include <linux/vfs.h>
3548+#include <linux/vmalloc.h>
3549+#include <linux/spinlock.h>
3550+#include <linux/smp_lock.h>
3551+#include <linux/exportfs.h>
3552+
3553+#include "squashfs.h"
3554+
3555+int get_fragment_location(struct super_block *s, unsigned int fragment,
3556+ long long *fragment_start_block,
3557+ unsigned int *fragment_size)
3558+{
3559+ struct squashfs_sb_info *msblk = s->s_fs_info;
3560+ long long start_block =
3561+ msblk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)];
3562+ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment);
3563+ struct squashfs_fragment_entry fragment_entry;
3564+
3565+ if (msblk->swap) {
3566+ struct squashfs_fragment_entry sfragment_entry;
3567+
3568+ if (!squashfs_get_cached_block(s, &sfragment_entry, start_block, offset,
3569+ sizeof(sfragment_entry), &start_block, &offset))
3570+ goto out;
3571+ SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry);
3572+ } else
3573+ if (!squashfs_get_cached_block(s, &fragment_entry, start_block, offset,
3574+ sizeof(fragment_entry), &start_block, &offset))
3575+ goto out;
3576+
3577+ *fragment_start_block = fragment_entry.start_block;
3578+ *fragment_size = fragment_entry.size;
3579+
3580+ return 1;
3581+
3582+out:
3583+ return 0;
3584+}
3585+
3586+
3587+void release_cached_fragment(struct squashfs_sb_info *msblk,
3588+ struct squashfs_cache_entry *fragment)
3589+{
3590+ squashfs_cache_put(msblk->fragment_cache, fragment);
3591+}
3592+
3593+
3594+struct squashfs_cache_entry *get_cached_fragment(struct super_block *s,
3595+ long long start_block, int length)
3596+{
3597+ struct squashfs_sb_info *msblk = s->s_fs_info;
3598+
3599+ return squashfs_cache_get(s, msblk->fragment_cache, start_block, length);
3600+}
3601+
3602+
3603+int read_fragment_index_table(struct super_block *s)
3604+{
3605+ struct squashfs_sb_info *msblk = s->s_fs_info;
3606+ struct squashfs_super_block *sblk = &msblk->sblk;
3607+ unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments);
3608+
3609+ if(length == 0)
3610+ return 1;
3611+
3612+ /* Allocate fragment index table */
3613+ msblk->fragment_index = kmalloc(length, GFP_KERNEL);
3614+ if (msblk->fragment_index == NULL) {
3615+ ERROR("Failed to allocate fragment index table\n");
3616+ return 0;
3617+ }
3618+
3619+ if (!squashfs_read_data(s, (char *) msblk->fragment_index,
3620+ sblk->fragment_table_start, length |
3621+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) {
3622+ ERROR("unable to read fragment index table\n");
3623+ return 0;
3624+ }
3625+
3626+ if (msblk->swap) {
3627+ int i;
3628+ long long fragment;
3629+
3630+ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments); i++) {
3631+ SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment),
3632+ &msblk->fragment_index[i], 1);
3633+ msblk->fragment_index[i] = fragment;
3634+ }
3635+ }
3636+
3637+ return 1;
3638+}
3639diff -uNr a/fs/squashfs/id.c b/fs/squashfs/id.c
3640--- a/fs/squashfs/id.c 1969-12-31 16:00:00.000000000 -0800
3641+++ b/fs/squashfs/id.c 2008-08-13 16:14:50.000000000 -0700
3642@@ -0,0 +1,97 @@
3643+/*
3644+ * Squashfs - a compressed read only filesystem for Linux
3645+ *
3646+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3647+ * Phillip Lougher <phillip@lougher.demon.co.uk>
3648+ *
3649+ * This program is free software; you can redistribute it and/or
3650+ * modify it under the terms of the GNU General Public License
3651+ * as published by the Free Software Foundation; either version 2,
3652+ * or (at your option) any later version.
3653+ *
3654+ * This program is distributed in the hope that it will be useful,
3655+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3656+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3657+ * GNU General Public License for more details.
3658+ *
3659+ * You should have received a copy of the GNU General Public License
3660+ * along with this program; if not, write to the Free Software
3661+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3662+ *
3663+ * id.c
3664+ */
3665+
3666+#include <linux/squashfs_fs.h>
3667+#include <linux/module.h>
3668+#include <linux/zlib.h>
3669+#include <linux/fs.h>
3670+#include <linux/squashfs_fs_sb.h>
3671+#include <linux/squashfs_fs_i.h>
3672+#include <linux/buffer_head.h>
3673+#include <linux/vfs.h>
3674+#include <linux/vmalloc.h>
3675+#include <linux/spinlock.h>
3676+#include <linux/smp_lock.h>
3677+#include <linux/exportfs.h>
3678+
3679+#include "squashfs.h"
3680+
3681+int get_id(struct super_block *s, unsigned int index, unsigned int *id)
3682+{
3683+ struct squashfs_sb_info *msblk = s->s_fs_info;
3684+ long long start_block = msblk->id_table[SQUASHFS_ID_BLOCK(index)];
3685+ int offset = SQUASHFS_ID_BLOCK_OFFSET(index);
3686+
3687+ if (msblk->swap) {
3688+ unsigned int sid;
3689+
3690+ if (!squashfs_get_cached_block(s, &sid, start_block, offset,
3691+ sizeof(unsigned int), &start_block, &offset))
3692+ goto out;
3693+ SQUASHFS_SWAP_INTS((&sid), id, 1);
3694+ } else
3695+ if (!squashfs_get_cached_block(s, id, start_block, offset,
3696+ sizeof(unsigned int), &start_block, &offset))
3697+ goto out;
3698+
3699+ return 1;
3700+
3701+out:
3702+ return 0;
3703+}
3704+
3705+
3706+int read_id_index_table(struct super_block *s)
3707+{
3708+ struct squashfs_sb_info *msblk = s->s_fs_info;
3709+ struct squashfs_super_block *sblk = &msblk->sblk;
3710+ unsigned int length = SQUASHFS_ID_BLOCK_BYTES(sblk->no_ids);
3711+
3712+ TRACE("In read_id_index_table, length %d\n", length);
3713+
3714+ /* Allocate id index table */
3715+ msblk->id_table = kmalloc(length, GFP_KERNEL);
3716+ if (msblk->id_table == NULL) {
3717+ ERROR("Failed to allocate id index table\n");
3718+ return 0;
3719+ }
3720+
3721+ if (!squashfs_read_data(s, (char *) msblk->id_table,
3722+ sblk->id_table_start, length |
3723+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) {
3724+ ERROR("unable to read id index table\n");
3725+ return 0;
3726+ }
3727+
3728+ if (msblk->swap) {
3729+ int i;
3730+ long long block;
3731+
3732+ for (i = 0; i < SQUASHFS_ID_BLOCKS(sblk->no_ids); i++) {
3733+ SQUASHFS_SWAP_ID_BLOCKS((&block), &msblk->id_table[i], 1);
3734+ msblk->id_table[i] = block;
3735+ }
3736+ }
3737+
3738+ return 1;
3739+}
3740diff -uNr a/fs/squashfs/inode.c b/fs/squashfs/inode.c
3741--- a/fs/squashfs/inode.c 1969-12-31 16:00:00.000000000 -0800
3742+++ b/fs/squashfs/inode.c 2008-08-13 16:14:50.000000000 -0700
3743@@ -0,0 +1,340 @@
3744+/*
3745+ * Squashfs - a compressed read only filesystem for Linux
3746+ *
3747+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3748+ * Phillip Lougher <phillip@lougher.demon.co.uk>
3749+ *
3750+ * This program is free software; you can redistribute it and/or
3751+ * modify it under the terms of the GNU General Public License
3752+ * as published by the Free Software Foundation; either version 2,
3753+ * or (at your option) any later version.
3754+ *
3755+ * This program is distributed in the hope that it will be useful,
3756+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3757+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3758+ * GNU General Public License for more details.
3759+ *
3760+ * You should have received a copy of the GNU General Public License
3761+ * along with this program; if not, write to the Free Software
3762+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3763+ *
3764+ * inode.c
3765+ */
3766+
3767+#include <linux/squashfs_fs.h>
3768+#include <linux/module.h>
3769+#include <linux/zlib.h>
3770+#include <linux/fs.h>
3771+#include <linux/squashfs_fs_sb.h>
3772+#include <linux/squashfs_fs_i.h>
3773+#include <linux/buffer_head.h>
3774+#include <linux/vfs.h>
3775+#include <linux/vmalloc.h>
3776+#include <linux/spinlock.h>
3777+#include <linux/smp_lock.h>
3778+#include <linux/exportfs.h>
3779+
3780+#include "squashfs.h"
3781+
3782+static int squashfs_new_inode(struct super_block *s, struct inode *i,
3783+ struct squashfs_base_inode_header *inodeb)
3784+{
3785+ if(get_id(s, inodeb->uid, &i->i_uid) == 0)
3786+ goto out;
3787+ if(get_id(s, inodeb->guid, &i->i_gid) == 0)
3788+ goto out;
3789+
3790+ i->i_ino = inodeb->inode_number;
3791+ i->i_mtime.tv_sec = inodeb->mtime;
3792+ i->i_atime.tv_sec = inodeb->mtime;
3793+ i->i_ctime.tv_sec = inodeb->mtime;
3794+ i->i_mode = inodeb->mode;
3795+ i->i_size = 0;
3796+
3797+ return 1;
3798+
3799+out:
3800+ return 0;
3801+}
3802+
3803+
3804+struct inode *squashfs_iget(struct super_block *s,
3805+ squashfs_inode_t inode, unsigned int inode_number)
3806+{
3807+ struct squashfs_sb_info *msblk = s->s_fs_info;
3808+ struct inode *i = iget_locked(s, inode_number);
3809+
3810+ TRACE("Entered squashfs_iget\n");
3811+
3812+ if(i && (i->i_state & I_NEW)) {
3813+ (msblk->read_inode)(i, inode);
3814+ unlock_new_inode(i);
3815+ }
3816+
3817+ return i;
3818+}
3819+
3820+
3821+int squashfs_read_inode(struct inode *i, squashfs_inode_t inode)
3822+{
3823+ struct super_block *s = i->i_sb;
3824+ struct squashfs_sb_info *msblk = s->s_fs_info;
3825+ struct squashfs_super_block *sblk = &msblk->sblk;
3826+ long long block = SQUASHFS_INODE_BLK(inode) + sblk->inode_table_start;
3827+ unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
3828+ long long next_block;
3829+ unsigned int next_offset;
3830+ union squashfs_inode_header id, sid;
3831+ struct squashfs_base_inode_header *inodeb = &id.base, *sinodeb = &sid.base;
3832+
3833+ TRACE("Entered squashfs_read_inode\n");
3834+
3835+ if (msblk->swap) {
3836+ if (!squashfs_get_cached_block(s, sinodeb, block, offset,
3837+ sizeof(*sinodeb), &next_block, &next_offset))
3838+ goto failed_read;
3839+ SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb, sinodeb, sizeof(*sinodeb));
3840+ } else
3841+ if (!squashfs_get_cached_block(s, inodeb, block, offset,
3842+ sizeof(*inodeb), &next_block, &next_offset))
3843+ goto failed_read;
3844+
3845+ if(squashfs_new_inode(s, i, inodeb) == 0)
3846+ goto failed_read;
3847+
3848+ switch(inodeb->inode_type) {
3849+ case SQUASHFS_FILE_TYPE: {
3850+ unsigned int frag_size;
3851+ long long frag_blk;
3852+ struct squashfs_reg_inode_header *inodep = &id.reg;
3853+ struct squashfs_reg_inode_header *sinodep = &sid.reg;
3854+
3855+ if (msblk->swap) {
3856+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
3857+ sizeof(*sinodep), &next_block, &next_offset))
3858+ goto failed_read;
3859+ SQUASHFS_SWAP_REG_INODE_HEADER(inodep, sinodep);
3860+ } else
3861+ if (!squashfs_get_cached_block(s, inodep, block, offset,
3862+ sizeof(*inodep), &next_block, &next_offset))
3863+ goto failed_read;
3864+
3865+ frag_blk = SQUASHFS_INVALID_BLK;
3866+
3867+ if (inodep->fragment != SQUASHFS_INVALID_FRAG)
3868+ if(!get_fragment_location(s, inodep->fragment, &frag_blk,
3869+ &frag_size))
3870+ goto failed_read;
3871+
3872+ i->i_nlink = 1;
3873+ i->i_size = inodep->file_size;
3874+ i->i_fop = &generic_ro_fops;
3875+ i->i_mode |= S_IFREG;
3876+ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
3877+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
3878+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
3879+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
3880+ SQUASHFS_I(i)->start_block = inodep->start_block;
3881+ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
3882+ SQUASHFS_I(i)->offset = next_offset;
3883+ i->i_data.a_ops = &squashfs_aops;
3884+
3885+ TRACE("File inode %x:%x, start_block %llx, "
3886+ "block_list_start %llx, offset %x\n",
3887+ SQUASHFS_INODE_BLK(inode), offset,
3888+ inodep->start_block, next_block,
3889+ next_offset);
3890+ break;
3891+ }
3892+ case SQUASHFS_LREG_TYPE: {
3893+ unsigned int frag_size;
3894+ long long frag_blk;
3895+ struct squashfs_lreg_inode_header *inodep = &id.lreg;
3896+ struct squashfs_lreg_inode_header *sinodep = &sid.lreg;
3897+
3898+ if (msblk->swap) {
3899+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
3900+ sizeof(*sinodep), &next_block, &next_offset))
3901+ goto failed_read;
3902+ SQUASHFS_SWAP_LREG_INODE_HEADER(inodep, sinodep);
3903+ } else
3904+ if (!squashfs_get_cached_block(s, inodep, block, offset,
3905+ sizeof(*inodep), &next_block, &next_offset))
3906+ goto failed_read;
3907+
3908+ frag_blk = SQUASHFS_INVALID_BLK;
3909+
3910+ if (inodep->fragment != SQUASHFS_INVALID_FRAG)
3911+ if (!get_fragment_location(s, inodep->fragment, &frag_blk,
3912+ &frag_size))
3913+ goto failed_read;
3914+
3915+ i->i_nlink = inodep->nlink;
3916+ i->i_size = inodep->file_size;
3917+ i->i_fop = &generic_ro_fops;
3918+ i->i_mode |= S_IFREG;
3919+ i->i_blocks = ((inodep->file_size - inodep->sparse - 1) >> 9) + 1;
3920+
3921+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
3922+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
3923+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
3924+ SQUASHFS_I(i)->start_block = inodep->start_block;
3925+ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
3926+ SQUASHFS_I(i)->offset = next_offset;
3927+ i->i_data.a_ops = &squashfs_aops;
3928+
3929+ TRACE("File inode %x:%x, start_block %llx, "
3930+ "block_list_start %llx, offset %x\n",
3931+ SQUASHFS_INODE_BLK(inode), offset,
3932+ inodep->start_block, next_block,
3933+ next_offset);
3934+ break;
3935+ }
3936+ case SQUASHFS_DIR_TYPE: {
3937+ struct squashfs_dir_inode_header *inodep = &id.dir;
3938+ struct squashfs_dir_inode_header *sinodep = &sid.dir;
3939+
3940+ if (msblk->swap) {
3941+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
3942+ sizeof(*sinodep), &next_block, &next_offset))
3943+ goto failed_read;
3944+ SQUASHFS_SWAP_DIR_INODE_HEADER(inodep, sinodep);
3945+ } else
3946+ if (!squashfs_get_cached_block(s, inodep, block, offset,
3947+ sizeof(*inodep), &next_block, &next_offset))
3948+ goto failed_read;
3949+
3950+ i->i_nlink = inodep->nlink;
3951+ i->i_size = inodep->file_size;
3952+ i->i_op = &squashfs_dir_inode_ops;
3953+ i->i_fop = &squashfs_dir_ops;
3954+ i->i_mode |= S_IFDIR;
3955+ SQUASHFS_I(i)->start_block = inodep->start_block;
3956+ SQUASHFS_I(i)->offset = inodep->offset;
3957+ SQUASHFS_I(i)->u.s2.directory_index_count = 0;
3958+ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
3959+
3960+ TRACE("Directory inode %x:%x, start_block %x, offset "
3961+ "%x\n", SQUASHFS_INODE_BLK(inode),
3962+ offset, inodep->start_block,
3963+ inodep->offset);
3964+ break;
3965+ }
3966+ case SQUASHFS_LDIR_TYPE: {
3967+ struct squashfs_ldir_inode_header *inodep = &id.ldir;
3968+ struct squashfs_ldir_inode_header *sinodep = &sid.ldir;
3969+
3970+ if (msblk->swap) {
3971+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
3972+ sizeof(*sinodep), &next_block, &next_offset))
3973+ goto failed_read;
3974+ SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep, sinodep);
3975+ } else
3976+ if (!squashfs_get_cached_block(s, inodep, block, offset,
3977+ sizeof(*inodep), &next_block, &next_offset))
3978+ goto failed_read;
3979+
3980+ i->i_nlink = inodep->nlink;
3981+ i->i_size = inodep->file_size;
3982+ i->i_op = &squashfs_dir_inode_ops;
3983+ i->i_fop = &squashfs_dir_ops;
3984+ i->i_mode |= S_IFDIR;
3985+ SQUASHFS_I(i)->start_block = inodep->start_block;
3986+ SQUASHFS_I(i)->offset = inodep->offset;
3987+ SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
3988+ SQUASHFS_I(i)->u.s2.directory_index_offset = next_offset;
3989+ SQUASHFS_I(i)->u.s2.directory_index_count = inodep->i_count;
3990+ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
3991+
3992+ TRACE("Long directory inode %x:%x, start_block %x, offset %x\n",
3993+ SQUASHFS_INODE_BLK(inode), offset,
3994+ inodep->start_block, inodep->offset);
3995+ break;
3996+ }
3997+ case SQUASHFS_SYMLINK_TYPE: {
3998+ struct squashfs_symlink_inode_header *inodep = &id.symlink;
3999+ struct squashfs_symlink_inode_header *sinodep = &sid.symlink;
4000+
4001+ if (msblk->swap) {
4002+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
4003+ sizeof(*sinodep), &next_block, &next_offset))
4004+ goto failed_read;
4005+ SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep, sinodep);
4006+ } else
4007+ if (!squashfs_get_cached_block(s, inodep, block, offset,
4008+ sizeof(*inodep), &next_block, &next_offset))
4009+ goto failed_read;
4010+
4011+ i->i_nlink = inodep->nlink;
4012+ i->i_size = inodep->symlink_size;
4013+ i->i_op = &page_symlink_inode_operations;
4014+ i->i_data.a_ops = &squashfs_symlink_aops;
4015+ i->i_mode |= S_IFLNK;
4016+ SQUASHFS_I(i)->start_block = next_block;
4017+ SQUASHFS_I(i)->offset = next_offset;
4018+
4019+ TRACE("Symbolic link inode %x:%x, start_block %llx, offset %x\n",
4020+ SQUASHFS_INODE_BLK(inode), offset,
4021+ next_block, next_offset);
4022+ break;
4023+ }
4024+ case SQUASHFS_BLKDEV_TYPE:
4025+ case SQUASHFS_CHRDEV_TYPE: {
4026+ struct squashfs_dev_inode_header *inodep = &id.dev;
4027+ struct squashfs_dev_inode_header *sinodep = &sid.dev;
4028+
4029+ if (msblk->swap) {
4030+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
4031+ sizeof(*sinodep), &next_block, &next_offset))
4032+ goto failed_read;
4033+ SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, sinodep);
4034+ } else
4035+ if (!squashfs_get_cached_block(s, inodep, block, offset,
4036+ sizeof(*inodep), &next_block, &next_offset))
4037+ goto failed_read;
4038+
4039+ i->i_nlink = inodep->nlink;
4040+ i->i_mode |= (inodeb->inode_type == SQUASHFS_CHRDEV_TYPE) ?
4041+ S_IFCHR : S_IFBLK;
4042+ init_special_inode(i, i->i_mode, old_decode_dev(inodep->rdev));
4043+
4044+ TRACE("Device inode %x:%x, rdev %x\n",
4045+ SQUASHFS_INODE_BLK(inode), offset, inodep->rdev);
4046+ break;
4047+ }
4048+ case SQUASHFS_FIFO_TYPE:
4049+ case SQUASHFS_SOCKET_TYPE: {
4050+ struct squashfs_ipc_inode_header *inodep = &id.ipc;
4051+ struct squashfs_ipc_inode_header *sinodep = &sid.ipc;
4052+
4053+ if (msblk->swap) {
4054+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
4055+ sizeof(*sinodep), &next_block, &next_offset))
4056+ goto failed_read;
4057+ SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep);
4058+ } else
4059+ if (!squashfs_get_cached_block(s, inodep, block, offset,
4060+ sizeof(*inodep), &next_block, &next_offset))
4061+ goto failed_read;
4062+
4063+ i->i_nlink = inodep->nlink;
4064+ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
4065+ ? S_IFIFO : S_IFSOCK;
4066+ init_special_inode(i, i->i_mode, 0);
4067+ break;
4068+ }
4069+ default:
4070+ ERROR("Unknown inode type %d in squashfs_iget!\n",
4071+ inodeb->inode_type);
4072+ goto failed_read1;
4073+ }
4074+
4075+ return 1;
4076+
4077+failed_read:
4078+ ERROR("Unable to read inode [%llx:%x]\n", block, offset);
4079+
4080+failed_read1:
4081+ make_bad_inode(i);
4082+ return 0;
4083+}
4084diff -uNr a/fs/squashfs/Makefile b/fs/squashfs/Makefile
4085--- a/fs/squashfs/Makefile 1969-12-31 16:00:00.000000000 -0800
4086+++ b/fs/squashfs/Makefile 2008-08-13 16:14:50.000000000 -0700
4087@@ -0,0 +1,8 @@
4088+#
4089+# Makefile for the linux squashfs routines.
4090+#
4091+
4092+obj-$(CONFIG_SQUASHFS) += squashfs.o
4093+squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
4094+squashfs-y += namei.o super.o symlink.o
4095+#squashfs-y += squashfs2_0.o
4096diff -uNr a/fs/squashfs/namei.c b/fs/squashfs/namei.c
4097--- a/fs/squashfs/namei.c 1969-12-31 16:00:00.000000000 -0800
4098+++ b/fs/squashfs/namei.c 2008-08-13 16:14:50.000000000 -0700
4099@@ -0,0 +1,200 @@
4100+/*
4101+ * Squashfs - a compressed read only filesystem for Linux
4102+ *
4103+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
4104+ * Phillip Lougher <phillip@lougher.demon.co.uk>
4105+ *
4106+ * This program is free software; you can redistribute it and/or
4107+ * modify it under the terms of the GNU General Public License
4108+ * as published by the Free Software Foundation; either version 2,
4109+ * or (at your option) any later version.
4110+ *
4111+ * This program is distributed in the hope that it will be useful,
4112+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4113+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4114+ * GNU General Public License for more details.
4115+ *
4116+ * You should have received a copy of the GNU General Public License
4117+ * along with this program; if not, write to the Free Software
4118+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4119+ *
4120+ * namei.c
4121+ */
4122+
4123+#include <linux/squashfs_fs.h>
4124+#include <linux/module.h>
4125+#include <linux/zlib.h>
4126+#include <linux/fs.h>
4127+#include <linux/squashfs_fs_sb.h>
4128+#include <linux/squashfs_fs_i.h>
4129+#include <linux/buffer_head.h>
4130+#include <linux/vfs.h>
4131+#include <linux/vmalloc.h>
4132+#include <linux/spinlock.h>
4133+#include <linux/smp_lock.h>
4134+#include <linux/exportfs.h>
4135+
4136+#include "squashfs.h"
4137+
4138+static int get_dir_index_using_name(struct super_block *s,
4139+ long long *next_block, unsigned int *next_offset,
4140+ long long index_start, unsigned int index_offset, int i_count,
4141+ const char *name, int size)
4142+{
4143+ struct squashfs_sb_info *msblk = s->s_fs_info;
4144+ struct squashfs_super_block *sblk = &msblk->sblk;
4145+ int i, length = 0;
4146+ struct squashfs_dir_index *index;
4147+ char *str;
4148+
4149+ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
4150+
4151+ str = kmalloc(sizeof(struct squashfs_dir_index) +
4152+ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL);
4153+ if (str == NULL) {
4154+ ERROR("Failed to allocate squashfs_dir_index\n");
4155+ goto failure;
4156+ }
4157+
4158+ index = (struct squashfs_dir_index *) (str + SQUASHFS_NAME_LEN + 1);
4159+ strncpy(str, name, size);
4160+ str[size] = '\0';
4161+
4162+ for (i = 0; i < i_count; i++) {
4163+ if (msblk->swap) {
4164+ struct squashfs_dir_index sindex;
4165+ squashfs_get_cached_block(s, &sindex, index_start, index_offset,
4166+ sizeof(sindex), &index_start, &index_offset);
4167+ SQUASHFS_SWAP_DIR_INDEX(index, &sindex);
4168+ } else
4169+ squashfs_get_cached_block(s, index, index_start, index_offset,
4170+ sizeof(struct squashfs_dir_index), &index_start, &index_offset);
4171+
4172+ squashfs_get_cached_block(s, index->name, index_start, index_offset,
4173+ index->size + 1, &index_start, &index_offset);
4174+
4175+ index->name[index->size + 1] = '\0';
4176+
4177+ if (strcmp(index->name, str) > 0)
4178+ break;
4179+
4180+ length = index->index;
4181+ *next_block = index->start_block + sblk->directory_table_start;
4182+ }
4183+
4184+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
4185+ kfree(str);
4186+
4187+failure:
4188+ return length + 3;
4189+}
4190+
4191+
4192+static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry,
4193+ struct nameidata *nd)
4194+{
4195+ const unsigned char *name = dentry->d_name.name;
4196+ int len = dentry->d_name.len;
4197+ struct inode *inode = NULL;
4198+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
4199+ struct squashfs_super_block *sblk = &msblk->sblk;
4200+ long long next_block = SQUASHFS_I(i)->start_block +
4201+ sblk->directory_table_start;
4202+ int next_offset = SQUASHFS_I(i)->offset, length = 0, dir_count;
4203+ struct squashfs_dir_header dirh;
4204+ struct squashfs_dir_entry *dire;
4205+
4206+ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset);
4207+
4208+ dire = kmalloc(sizeof(struct squashfs_dir_entry) +
4209+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL);
4210+ if (dire == NULL) {
4211+ ERROR("Failed to allocate squashfs_dir_entry\n");
4212+ goto exit_lookup;
4213+ }
4214+
4215+ if (len > SQUASHFS_NAME_LEN)
4216+ goto exit_lookup;
4217+
4218+ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
4219+ SQUASHFS_I(i)->u.s2.directory_index_start,
4220+ SQUASHFS_I(i)->u.s2.directory_index_offset,
4221+ SQUASHFS_I(i)->u.s2.directory_index_count, name, len);
4222+
4223+ while (length < i_size_read(i)) {
4224+ /* read directory header */
4225+ if (msblk->swap) {
4226+ struct squashfs_dir_header sdirh;
4227+ if (!squashfs_get_cached_block(i->i_sb, &sdirh, next_block,
4228+ next_offset, sizeof(sdirh), &next_block, &next_offset))
4229+ goto failed_read;
4230+
4231+ length += sizeof(sdirh);
4232+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
4233+ } else {
4234+ if (!squashfs_get_cached_block(i->i_sb, &dirh, next_block,
4235+ next_offset, sizeof(dirh), &next_block, &next_offset))
4236+ goto failed_read;
4237+
4238+ length += sizeof(dirh);
4239+ }
4240+
4241+ dir_count = dirh.count + 1;
4242+ while (dir_count--) {
4243+ if (msblk->swap) {
4244+ struct squashfs_dir_entry sdire;
4245+ if (!squashfs_get_cached_block(i->i_sb, &sdire, next_block,
4246+ next_offset, sizeof(sdire), &next_block, &next_offset))
4247+ goto failed_read;
4248+
4249+ length += sizeof(sdire);
4250+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
4251+ } else {
4252+ if (!squashfs_get_cached_block(i->i_sb, dire, next_block,
4253+ next_offset, sizeof(*dire), &next_block, &next_offset))
4254+ goto failed_read;
4255+
4256+ length += sizeof(*dire);
4257+ }
4258+
4259+ if (!squashfs_get_cached_block(i->i_sb, dire->name, next_block,
4260+ next_offset, dire->size + 1, &next_block, &next_offset))
4261+ goto failed_read;
4262+
4263+ length += dire->size + 1;
4264+
4265+ if (name[0] < dire->name[0])
4266+ goto exit_lookup;
4267+
4268+ if ((len == dire->size + 1) && !strncmp(name, dire->name, len)) {
4269+ squashfs_inode_t ino = SQUASHFS_MKINODE(dirh.start_block,
4270+ dire->offset);
4271+
4272+ TRACE("calling squashfs_iget for directory entry %s, inode"
4273+ " %x:%x, %d\n", name, dirh.start_block, dire->offset,
4274+ dirh.inode_number + dire->inode_number);
4275+
4276+ inode = squashfs_iget(i->i_sb, ino, dirh.inode_number + dire->inode_number);
4277+
4278+ goto exit_lookup;
4279+ }
4280+ }
4281+ }
4282+
4283+exit_lookup:
4284+ kfree(dire);
4285+ if (inode)
4286+ return d_splice_alias(inode, dentry);
4287+ d_add(dentry, inode);
4288+ return ERR_PTR(0);
4289+
4290+failed_read:
4291+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
4292+ next_offset);
4293+ goto exit_lookup;
4294+}
4295+
4296+
4297+const struct inode_operations squashfs_dir_inode_ops = {
4298+ .lookup = squashfs_lookup
4299+};
4300diff -uNr a/fs/squashfs/squashfs2_0.c b/fs/squashfs/squashfs2_0.c
4301--- a/fs/squashfs/squashfs2_0.c 1969-12-31 16:00:00.000000000 -0800
4302+++ b/fs/squashfs/squashfs2_0.c 2008-08-13 16:14:50.000000000 -0700
4303@@ -0,0 +1,740 @@
4304+/*
4305+ * Squashfs - a compressed read only filesystem for Linux
4306+ *
4307+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
4308+ * Phillip Lougher <phillip@lougher.demon.co.uk>
4309+ *
4310+ * This program is free software; you can redistribute it and/or
4311+ * modify it under the terms of the GNU General Public License
4312+ * as published by the Free Software Foundation; either version 2,
4313+ * or (at your option) any later version.
4314+ *
4315+ * This program is distributed in the hope that it will be useful,
4316+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4317+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4318+ * GNU General Public License for more details.
4319+ *
4320+ * You should have received a copy of the GNU General Public License
4321+ * along with this program; if not, write to the Free Software
4322+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4323+ *
4324+ * squashfs2_0.c
4325+ */
4326+
4327+#include <linux/squashfs_fs.h>
4328+#include <linux/module.h>
4329+#include <linux/zlib.h>
4330+#include <linux/fs.h>
4331+#include <linux/squashfs_fs_sb.h>
4332+#include <linux/squashfs_fs_i.h>
4333+
4334+#include "squashfs.h"
4335+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir);
4336+static struct dentry *squashfs_lookup_2(struct inode *, struct dentry *,
4337+ struct nameidata *);
4338+
4339+static struct file_operations squashfs_dir_ops_2 = {
4340+ .read = generic_read_dir,
4341+ .readdir = squashfs_readdir_2
4342+};
4343+
4344+static struct inode_operations squashfs_dir_inode_ops_2 = {
4345+ .lookup = squashfs_lookup_2
4346+};
4347+
4348+static unsigned char squashfs_filetype_table[] = {
4349+ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
4350+};
4351+
4352+static int read_fragment_index_table_2(struct super_block *s)
4353+{
4354+ struct squashfs_sb_info *msblk = s->s_fs_info;
4355+ struct squashfs_super_block *sblk = &msblk->sblk;
4356+
4357+ if (!(msblk->fragment_index_2 = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES_2
4358+ (sblk->fragments), GFP_KERNEL))) {
4359+ ERROR("Failed to allocate uid/gid table\n");
4360+ return 0;
4361+ }
4362+
4363+ if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) &&
4364+ !squashfs_read_data(s, (char *)
4365+ msblk->fragment_index_2,
4366+ sblk->fragment_table_start,
4367+ SQUASHFS_FRAGMENT_INDEX_BYTES_2
4368+ (sblk->fragments) |
4369+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments))) {
4370+ ERROR("unable to read fragment index table\n");
4371+ return 0;
4372+ }
4373+
4374+ if (msblk->swap) {
4375+ int i;
4376+ unsigned int fragment;
4377+
4378+ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES_2(sblk->fragments);
4379+ i++) {
4380+ SQUASHFS_SWAP_FRAGMENT_INDEXES_2((&fragment),
4381+ &msblk->fragment_index_2[i], 1);
4382+ msblk->fragment_index_2[i] = fragment;
4383+ }
4384+ }
4385+
4386+ return 1;
4387+}
4388+
4389+
4390+static int get_fragment_location_2(struct super_block *s, unsigned int fragment,
4391+ long long *fragment_start_block,
4392+ unsigned int *fragment_size)
4393+{
4394+ struct squashfs_sb_info *msblk = s->s_fs_info;
4395+ long long start_block =
4396+ msblk->fragment_index_2[SQUASHFS_FRAGMENT_INDEX_2(fragment)];
4397+ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET_2(fragment);
4398+ struct squashfs_fragment_entry_2 fragment_entry;
4399+
4400+ if (msblk->swap) {
4401+ struct squashfs_fragment_entry_2 sfragment_entry;
4402+
4403+ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry,
4404+ start_block, offset,
4405+ sizeof(sfragment_entry), &start_block,
4406+ &offset))
4407+ goto out;
4408+ SQUASHFS_SWAP_FRAGMENT_ENTRY_2(&fragment_entry, &sfragment_entry);
4409+ } else
4410+ if (!squashfs_get_cached_block(s, (char *) &fragment_entry,
4411+ start_block, offset,
4412+ sizeof(fragment_entry), &start_block,
4413+ &offset))
4414+ goto out;
4415+
4416+ *fragment_start_block = fragment_entry.start_block;
4417+ *fragment_size = fragment_entry.size;
4418+
4419+ return 1;
4420+
4421+out:
4422+ return 0;
4423+}
4424+
4425+
4426+static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i,
4427+ struct squashfs_base_inode_header_2 *inodeb, unsigned int ino)
4428+{
4429+ struct squashfs_super_block *sblk = &msblk->sblk;
4430+
4431+ i->i_ino = ino;
4432+ i->i_mtime.tv_sec = sblk->mkfs_time;
4433+ i->i_atime.tv_sec = sblk->mkfs_time;
4434+ i->i_ctime.tv_sec = sblk->mkfs_time;
4435+ i->i_uid = msblk->uid[inodeb->uid];
4436+ i->i_mode = inodeb->mode;
4437+ i->i_nlink = 1;
4438+ i->i_size = 0;
4439+ if (inodeb->guid == SQUASHFS_GUIDS)
4440+ i->i_gid = i->i_uid;
4441+ else
4442+ i->i_gid = msblk->guid[inodeb->guid];
4443+}
4444+
4445+
4446+static int squashfs_read_inode_2(struct inode *i, squashfs_inode_t inode)
4447+{
4448+ struct super_block *s = i->i_sb;
4449+ struct squashfs_sb_info *msblk = s->s_fs_info;
4450+ struct squashfs_super_block *sblk = &msblk->sblk;
4451+ unsigned int block = SQUASHFS_INODE_BLK(inode) +
4452+ sblk->inode_table_start;
4453+ unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
4454+ unsigned int ino = SQUASHFS_MK_VFS_INODE(block -
4455+ sblk->inode_table_start, offset);
4456+ long long next_block;
4457+ unsigned int next_offset;
4458+ union squashfs_inode_header_2 id, sid;
4459+ struct squashfs_base_inode_header_2 *inodeb = &id.base,
4460+ *sinodeb = &sid.base;
4461+
4462+ TRACE("Entered squashfs_read_inode_2\n");
4463+
4464+ if (msblk->swap) {
4465+ if (!squashfs_get_cached_block(s, (char *) sinodeb, block,
4466+ offset, sizeof(*sinodeb), &next_block,
4467+ &next_offset))
4468+ goto failed_read;
4469+ SQUASHFS_SWAP_BASE_INODE_HEADER_2(inodeb, sinodeb,
4470+ sizeof(*sinodeb));
4471+ } else
4472+ if (!squashfs_get_cached_block(s, (char *) inodeb, block,
4473+ offset, sizeof(*inodeb), &next_block,
4474+ &next_offset))
4475+ goto failed_read;
4476+
4477+ squashfs_new_inode(msblk, i, inodeb, ino);
4478+
4479+ switch(inodeb->inode_type) {
4480+ case SQUASHFS_FILE_TYPE: {
4481+ struct squashfs_reg_inode_header_2 *inodep = &id.reg;
4482+ struct squashfs_reg_inode_header_2 *sinodep = &sid.reg;
4483+ long long frag_blk;
4484+ unsigned int frag_size = 0;
4485+
4486+ if (msblk->swap) {
4487+ if (!squashfs_get_cached_block(s, (char *)
4488+ sinodep, block, offset,
4489+ sizeof(*sinodep), &next_block,
4490+ &next_offset))
4491+ goto failed_read;
4492+ SQUASHFS_SWAP_REG_INODE_HEADER_2(inodep, sinodep);
4493+ } else
4494+ if (!squashfs_get_cached_block(s, (char *)
4495+ inodep, block, offset,
4496+ sizeof(*inodep), &next_block,
4497+ &next_offset))
4498+ goto failed_read;
4499+
4500+ frag_blk = SQUASHFS_INVALID_BLK;
4501+ if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
4502+ !get_fragment_location_2(s,
4503+ inodep->fragment, &frag_blk, &frag_size))
4504+ goto failed_read;
4505+
4506+ i->i_size = inodep->file_size;
4507+ i->i_fop = &generic_ro_fops;
4508+ i->i_mode |= S_IFREG;
4509+ i->i_mtime.tv_sec = inodep->mtime;
4510+ i->i_atime.tv_sec = inodep->mtime;
4511+ i->i_ctime.tv_sec = inodep->mtime;
4512+ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
4513+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
4514+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
4515+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
4516+ SQUASHFS_I(i)->start_block = inodep->start_block;
4517+ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
4518+ SQUASHFS_I(i)->offset = next_offset;
4519+ i->i_data.a_ops = &squashfs_aops;
4520+
4521+ TRACE("File inode %x:%x, start_block %x, "
4522+ "block_list_start %llx, offset %x\n",
4523+ SQUASHFS_INODE_BLK(inode), offset,
4524+ inodep->start_block, next_block,
4525+ next_offset);
4526+ break;
4527+ }
4528+ case SQUASHFS_DIR_TYPE: {
4529+ struct squashfs_dir_inode_header_2 *inodep = &id.dir;
4530+ struct squashfs_dir_inode_header_2 *sinodep = &sid.dir;
4531+
4532+ if (msblk->swap) {
4533+ if (!squashfs_get_cached_block(s, (char *)
4534+ sinodep, block, offset,
4535+ sizeof(*sinodep), &next_block,
4536+ &next_offset))
4537+ goto failed_read;
4538+ SQUASHFS_SWAP_DIR_INODE_HEADER_2(inodep, sinodep);
4539+ } else
4540+ if (!squashfs_get_cached_block(s, (char *)
4541+ inodep, block, offset,
4542+ sizeof(*inodep), &next_block,
4543+ &next_offset))
4544+ goto failed_read;
4545+
4546+ i->i_size = inodep->file_size;
4547+ i->i_op = &squashfs_dir_inode_ops_2;
4548+ i->i_fop = &squashfs_dir_ops_2;
4549+ i->i_mode |= S_IFDIR;
4550+ i->i_mtime.tv_sec = inodep->mtime;
4551+ i->i_atime.tv_sec = inodep->mtime;
4552+ i->i_ctime.tv_sec = inodep->mtime;
4553+ SQUASHFS_I(i)->start_block = inodep->start_block;
4554+ SQUASHFS_I(i)->offset = inodep->offset;
4555+ SQUASHFS_I(i)->u.s2.directory_index_count = 0;
4556+ SQUASHFS_I(i)->u.s2.parent_inode = 0;
4557+
4558+ TRACE("Directory inode %x:%x, start_block %x, offset "
4559+ "%x\n", SQUASHFS_INODE_BLK(inode),
4560+ offset, inodep->start_block,
4561+ inodep->offset);
4562+ break;
4563+ }
4564+ case SQUASHFS_LDIR_TYPE: {
4565+ struct squashfs_ldir_inode_header_2 *inodep = &id.ldir;
4566+ struct squashfs_ldir_inode_header_2 *sinodep = &sid.ldir;
4567+
4568+ if (msblk->swap) {
4569+ if (!squashfs_get_cached_block(s, (char *)
4570+ sinodep, block, offset,
4571+ sizeof(*sinodep), &next_block,
4572+ &next_offset))
4573+ goto failed_read;
4574+ SQUASHFS_SWAP_LDIR_INODE_HEADER_2(inodep,
4575+ sinodep);
4576+ } else
4577+ if (!squashfs_get_cached_block(s, (char *)
4578+ inodep, block, offset,
4579+ sizeof(*inodep), &next_block,
4580+ &next_offset))
4581+ goto failed_read;
4582+
4583+ i->i_size = inodep->file_size;
4584+ i->i_op = &squashfs_dir_inode_ops_2;
4585+ i->i_fop = &squashfs_dir_ops_2;
4586+ i->i_mode |= S_IFDIR;
4587+ i->i_mtime.tv_sec = inodep->mtime;
4588+ i->i_atime.tv_sec = inodep->mtime;
4589+ i->i_ctime.tv_sec = inodep->mtime;
4590+ SQUASHFS_I(i)->start_block = inodep->start_block;
4591+ SQUASHFS_I(i)->offset = inodep->offset;
4592+ SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
4593+ SQUASHFS_I(i)->u.s2.directory_index_offset =
4594+ next_offset;
4595+ SQUASHFS_I(i)->u.s2.directory_index_count =
4596+ inodep->i_count;
4597+ SQUASHFS_I(i)->u.s2.parent_inode = 0;
4598+
4599+ TRACE("Long directory inode %x:%x, start_block %x, "
4600+ "offset %x\n",
4601+ SQUASHFS_INODE_BLK(inode), offset,
4602+ inodep->start_block, inodep->offset);
4603+ break;
4604+ }
4605+ case SQUASHFS_SYMLINK_TYPE: {
4606+ struct squashfs_symlink_inode_header_2 *inodep =
4607+ &id.symlink;
4608+ struct squashfs_symlink_inode_header_2 *sinodep =
4609+ &sid.symlink;
4610+
4611+ if (msblk->swap) {
4612+ if (!squashfs_get_cached_block(s, (char *)
4613+ sinodep, block, offset,
4614+ sizeof(*sinodep), &next_block,
4615+ &next_offset))
4616+ goto failed_read;
4617+ SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(inodep,
4618+ sinodep);
4619+ } else
4620+ if (!squashfs_get_cached_block(s, (char *)
4621+ inodep, block, offset,
4622+ sizeof(*inodep), &next_block,
4623+ &next_offset))
4624+ goto failed_read;
4625+
4626+ i->i_size = inodep->symlink_size;
4627+ i->i_op = &page_symlink_inode_operations;
4628+ i->i_data.a_ops = &squashfs_symlink_aops;
4629+ i->i_mode |= S_IFLNK;
4630+ SQUASHFS_I(i)->start_block = next_block;
4631+ SQUASHFS_I(i)->offset = next_offset;
4632+
4633+ TRACE("Symbolic link inode %x:%x, start_block %llx, "
4634+ "offset %x\n",
4635+ SQUASHFS_INODE_BLK(inode), offset,
4636+ next_block, next_offset);
4637+ break;
4638+ }
4639+ case SQUASHFS_BLKDEV_TYPE:
4640+ case SQUASHFS_CHRDEV_TYPE: {
4641+ struct squashfs_dev_inode_header_2 *inodep = &id.dev;
4642+ struct squashfs_dev_inode_header_2 *sinodep = &sid.dev;
4643+
4644+ if (msblk->swap) {
4645+ if (!squashfs_get_cached_block(s, (char *)
4646+ sinodep, block, offset,
4647+ sizeof(*sinodep), &next_block,
4648+ &next_offset))
4649+ goto failed_read;
4650+ SQUASHFS_SWAP_DEV_INODE_HEADER_2(inodep, sinodep);
4651+ } else
4652+ if (!squashfs_get_cached_block(s, (char *)
4653+ inodep, block, offset,
4654+ sizeof(*inodep), &next_block,
4655+ &next_offset))
4656+ goto failed_read;
4657+
4658+ i->i_mode |= (inodeb->inode_type ==
4659+ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR :
4660+ S_IFBLK;
4661+ init_special_inode(i, i->i_mode,
4662+ old_decode_dev(inodep->rdev));
4663+
4664+ TRACE("Device inode %x:%x, rdev %x\n",
4665+ SQUASHFS_INODE_BLK(inode), offset,
4666+ inodep->rdev);
4667+ break;
4668+ }
4669+ case SQUASHFS_FIFO_TYPE:
4670+ case SQUASHFS_SOCKET_TYPE: {
4671+
4672+ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
4673+ ? S_IFIFO : S_IFSOCK;
4674+ init_special_inode(i, i->i_mode, 0);
4675+ break;
4676+ }
4677+ default:
4678+ ERROR("Unknown inode type %d in squashfs_iget!\n",
4679+ inodeb->inode_type);
4680+ goto failed_read1;
4681+ }
4682+
4683+ return 1;
4684+
4685+failed_read:
4686+ ERROR("Unable to read inode [%x:%x]\n", block, offset);
4687+
4688+failed_read1:
4689+ return 0;
4690+}
4691+
4692+
4693+static int get_dir_index_using_offset(struct super_block *s, long long
4694+ *next_block, unsigned int *next_offset,
4695+ long long index_start,
4696+ unsigned int index_offset, int i_count,
4697+ long long f_pos)
4698+{
4699+ struct squashfs_sb_info *msblk = s->s_fs_info;
4700+ struct squashfs_super_block *sblk = &msblk->sblk;
4701+ int i, length = 0;
4702+ struct squashfs_dir_index_2 index;
4703+
4704+ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
4705+ i_count, (unsigned int) f_pos);
4706+
4707+ if (f_pos == 0)
4708+ goto finish;
4709+
4710+ for (i = 0; i < i_count; i++) {
4711+ if (msblk->swap) {
4712+ struct squashfs_dir_index_2 sindex;
4713+ squashfs_get_cached_block(s, (char *) &sindex,
4714+ index_start, index_offset,
4715+ sizeof(sindex), &index_start,
4716+ &index_offset);
4717+ SQUASHFS_SWAP_DIR_INDEX_2(&index, &sindex);
4718+ } else
4719+ squashfs_get_cached_block(s, (char *) &index,
4720+ index_start, index_offset,
4721+ sizeof(index), &index_start,
4722+ &index_offset);
4723+
4724+ if (index.index > f_pos)
4725+ break;
4726+
4727+ squashfs_get_cached_block(s, NULL, index_start, index_offset,
4728+ index.size + 1, &index_start,
4729+ &index_offset);
4730+
4731+ length = index.index;
4732+ *next_block = index.start_block + sblk->directory_table_start;
4733+ }
4734+
4735+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
4736+
4737+finish:
4738+ return length;
4739+}
4740+
4741+
4742+static int get_dir_index_using_name(struct super_block *s, long long
4743+ *next_block, unsigned int *next_offset,
4744+ long long index_start,
4745+ unsigned int index_offset, int i_count,
4746+ const char *name, int size)
4747+{
4748+ struct squashfs_sb_info *msblk = s->s_fs_info;
4749+ struct squashfs_super_block *sblk = &msblk->sblk;
4750+ int i, length = 0;
4751+ struct squashfs_dir_index_2 *index;
4752+ char *str;
4753+
4754+ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
4755+
4756+ if (!(str = kmalloc(sizeof(struct squashfs_dir_index) +
4757+ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) {
4758+ ERROR("Failed to allocate squashfs_dir_index\n");
4759+ goto failure;
4760+ }
4761+
4762+ index = (struct squashfs_dir_index_2 *) (str + SQUASHFS_NAME_LEN + 1);
4763+ strncpy(str, name, size);
4764+ str[size] = '\0';
4765+
4766+ for (i = 0; i < i_count; i++) {
4767+ if (msblk->swap) {
4768+ struct squashfs_dir_index_2 sindex;
4769+ squashfs_get_cached_block(s, (char *) &sindex,
4770+ index_start, index_offset,
4771+ sizeof(sindex), &index_start,
4772+ &index_offset);
4773+ SQUASHFS_SWAP_DIR_INDEX_2(index, &sindex);
4774+ } else
4775+ squashfs_get_cached_block(s, (char *) index,
4776+ index_start, index_offset,
4777+ sizeof(struct squashfs_dir_index_2),
4778+ &index_start, &index_offset);
4779+
4780+ squashfs_get_cached_block(s, index->name, index_start,
4781+ index_offset, index->size + 1,
4782+ &index_start, &index_offset);
4783+
4784+ index->name[index->size + 1] = '\0';
4785+
4786+ if (strcmp(index->name, str) > 0)
4787+ break;
4788+
4789+ length = index->index;
4790+ *next_block = index->start_block + sblk->directory_table_start;
4791+ }
4792+
4793+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
4794+ kfree(str);
4795+failure:
4796+ return length;
4797+}
4798+
4799+
4800+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir)
4801+{
4802+ struct inode *i = file->f_dentry->d_inode;
4803+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
4804+ struct squashfs_super_block *sblk = &msblk->sblk;
4805+ long long next_block = SQUASHFS_I(i)->start_block +
4806+ sblk->directory_table_start;
4807+ int next_offset = SQUASHFS_I(i)->offset, length = 0,
4808+ dir_count;
4809+ struct squashfs_dir_header_2 dirh;
4810+ struct squashfs_dir_entry_2 *dire;
4811+
4812+ TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset);
4813+
4814+ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) +
4815+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) {
4816+ ERROR("Failed to allocate squashfs_dir_entry\n");
4817+ goto finish;
4818+ }
4819+
4820+ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
4821+ SQUASHFS_I(i)->u.s2.directory_index_start,
4822+ SQUASHFS_I(i)->u.s2.directory_index_offset,
4823+ SQUASHFS_I(i)->u.s2.directory_index_count,
4824+ file->f_pos);
4825+
4826+ while (length < i_size_read(i)) {
4827+ /* read directory header */
4828+ if (msblk->swap) {
4829+ struct squashfs_dir_header_2 sdirh;
4830+
4831+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
4832+ next_block, next_offset, sizeof(sdirh),
4833+ &next_block, &next_offset))
4834+ goto failed_read;
4835+
4836+ length += sizeof(sdirh);
4837+ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
4838+ } else {
4839+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
4840+ next_block, next_offset, sizeof(dirh),
4841+ &next_block, &next_offset))
4842+ goto failed_read;
4843+
4844+ length += sizeof(dirh);
4845+ }
4846+
4847+ dir_count = dirh.count + 1;
4848+ while (dir_count--) {
4849+ if (msblk->swap) {
4850+ struct squashfs_dir_entry_2 sdire;
4851+ if (!squashfs_get_cached_block(i->i_sb, (char *)
4852+ &sdire, next_block, next_offset,
4853+ sizeof(sdire), &next_block,
4854+ &next_offset))
4855+ goto failed_read;
4856+
4857+ length += sizeof(sdire);
4858+ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
4859+ } else {
4860+ if (!squashfs_get_cached_block(i->i_sb, (char *)
4861+ dire, next_block, next_offset,
4862+ sizeof(*dire), &next_block,
4863+ &next_offset))
4864+ goto failed_read;
4865+
4866+ length += sizeof(*dire);
4867+ }
4868+
4869+ if (!squashfs_get_cached_block(i->i_sb, dire->name,
4870+ next_block, next_offset,
4871+ dire->size + 1, &next_block,
4872+ &next_offset))
4873+ goto failed_read;
4874+
4875+ length += dire->size + 1;
4876+
4877+ if (file->f_pos >= length)
4878+ continue;
4879+
4880+ dire->name[dire->size + 1] = '\0';
4881+
4882+ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n",
4883+ (unsigned int) dirent, dire->name,
4884+ dire->size + 1, (int) file->f_pos,
4885+ dirh.start_block, dire->offset,
4886+ squashfs_filetype_table[dire->type]);
4887+
4888+ if (filldir(dirent, dire->name, dire->size + 1,
4889+ file->f_pos, SQUASHFS_MK_VFS_INODE(
4890+ dirh.start_block, dire->offset),
4891+ squashfs_filetype_table[dire->type])
4892+ < 0) {
4893+ TRACE("Filldir returned less than 0\n");
4894+ goto finish;
4895+ }
4896+ file->f_pos = length;
4897+ }
4898+ }
4899+
4900+finish:
4901+ kfree(dire);
4902+ return 0;
4903+
4904+failed_read:
4905+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
4906+ next_offset);
4907+ kfree(dire);
4908+ return 0;
4909+}
4910+
4911+
4912+static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry,
4913+ struct nameidata *nd)
4914+{
4915+ const unsigned char *name = dentry->d_name.name;
4916+ int len = dentry->d_name.len;
4917+ struct inode *inode = NULL;
4918+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
4919+ struct squashfs_super_block *sblk = &msblk->sblk;
4920+ long long next_block = SQUASHFS_I(i)->start_block +
4921+ sblk->directory_table_start;
4922+ int next_offset = SQUASHFS_I(i)->offset, length = 0,
4923+ dir_count;
4924+ struct squashfs_dir_header_2 dirh;
4925+ struct squashfs_dir_entry_2 *dire;
4926+ int sorted = sblk->s_major == 2 && sblk->s_minor >= 1;
4927+
4928+ TRACE("Entered squashfs_lookup_2 [%llx:%x]\n", next_block, next_offset);
4929+
4930+ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) +
4931+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) {
4932+ ERROR("Failed to allocate squashfs_dir_entry\n");
4933+ goto exit_loop;
4934+ }
4935+
4936+ if (len > SQUASHFS_NAME_LEN)
4937+ goto exit_loop;
4938+
4939+ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
4940+ SQUASHFS_I(i)->u.s2.directory_index_start,
4941+ SQUASHFS_I(i)->u.s2.directory_index_offset,
4942+ SQUASHFS_I(i)->u.s2.directory_index_count, name,
4943+ len);
4944+
4945+ while (length < i_size_read(i)) {
4946+ /* read directory header */
4947+ if (msblk->swap) {
4948+ struct squashfs_dir_header_2 sdirh;
4949+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
4950+ next_block, next_offset, sizeof(sdirh),
4951+ &next_block, &next_offset))
4952+ goto failed_read;
4953+
4954+ length += sizeof(sdirh);
4955+ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
4956+ } else {
4957+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
4958+ next_block, next_offset, sizeof(dirh),
4959+ &next_block, &next_offset))
4960+ goto failed_read;
4961+
4962+ length += sizeof(dirh);
4963+ }
4964+
4965+ dir_count = dirh.count + 1;
4966+ while (dir_count--) {
4967+ if (msblk->swap) {
4968+ struct squashfs_dir_entry_2 sdire;
4969+ if (!squashfs_get_cached_block(i->i_sb, (char *)
4970+ &sdire, next_block,next_offset,
4971+ sizeof(sdire), &next_block,
4972+ &next_offset))
4973+ goto failed_read;
4974+
4975+ length += sizeof(sdire);
4976+ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
4977+ } else {
4978+ if (!squashfs_get_cached_block(i->i_sb, (char *)
4979+ dire, next_block,next_offset,
4980+ sizeof(*dire), &next_block,
4981+ &next_offset))
4982+ goto failed_read;
4983+
4984+ length += sizeof(*dire);
4985+ }
4986+
4987+ if (!squashfs_get_cached_block(i->i_sb, dire->name,
4988+ next_block, next_offset, dire->size + 1,
4989+ &next_block, &next_offset))
4990+ goto failed_read;
4991+
4992+ length += dire->size + 1;
4993+
4994+ if (sorted && name[0] < dire->name[0])
4995+ goto exit_loop;
4996+
4997+ if ((len == dire->size + 1) && !strncmp(name,
4998+ dire->name, len)) {
4999+ squashfs_inode_t ino =
5000+ SQUASHFS_MKINODE(dirh.start_block,
5001+ dire->offset);
5002+ unsigned int inode_number = SQUASHFS_MK_VFS_INODE(dirh.start_block,
5003+ dire->offset);
5004+
5005+ TRACE("calling squashfs_iget for directory "
5006+ "entry %s, inode %x:%x, %lld\n", name,
5007+ dirh.start_block, dire->offset, ino);
5008+
5009+ inode = squashfs_iget(i->i_sb, ino, inode_number);
5010+
5011+ goto exit_loop;
5012+ }
5013+ }
5014+ }
5015+
5016+exit_loop:
5017+ kfree(dire);
5018+ d_add(dentry, inode);
5019+ return ERR_PTR(0);
5020+
5021+failed_read:
5022+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
5023+ next_offset);
5024+ goto exit_loop;
5025+}
5026+
5027+
5028+int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
5029+{
5030+ struct squashfs_super_block *sblk = &msblk->sblk;
5031+
5032+ msblk->read_inode = squashfs_read_inode_2;
5033+ msblk->read_fragment_index_table = read_fragment_index_table_2;
5034+
5035+ sblk->bytes_used = sblk->bytes_used_2;
5036+ sblk->uid_start = sblk->uid_start_2;
5037+ sblk->guid_start = sblk->guid_start_2;
5038+ sblk->inode_table_start = sblk->inode_table_start_2;
5039+ sblk->directory_table_start = sblk->directory_table_start_2;
5040+ sblk->fragment_table_start = sblk->fragment_table_start_2;
5041+
5042+ return 1;
5043+}
5044diff -uNr a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h
5045--- a/fs/squashfs/squashfs.h 1969-12-31 16:00:00.000000000 -0800
5046+++ b/fs/squashfs/squashfs.h 2008-08-13 16:14:50.000000000 -0700
5047@@ -0,0 +1,122 @@
5048+/*
5049+ * Squashfs - a compressed read only filesystem for Linux
5050+ *
5051+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5052+ * Phillip Lougher <phillip@lougher.demon.co.uk>
5053+ *
5054+ * This program is free software; you can redistribute it and/or
5055+ * modify it under the terms of the GNU General Public License
5056+ * as published by the Free Software Foundation; either version 2,
5057+ * or (at your option) any later version.
5058+ *
5059+ * This program is distributed in the hope that it will be useful,
5060+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5061+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5062+ * GNU General Public License for more details.
5063+ *
5064+ * You should have received a copy of the GNU General Public License
5065+ * along with this program; if not, write to the Free Software
5066+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5067+ *
5068+ * squashfs.h
5069+ */
5070+
5071+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
5072+#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY
5073+#endif
5074+
5075+#ifdef SQUASHFS_TRACE
5076+#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args)
5077+#else
5078+#define TRACE(s, args...) {}
5079+#endif
5080+
5081+#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args)
5082+
5083+#define SERROR(s, args...) do { \
5084+ if (!silent) \
5085+ printk(KERN_ERR "SQUASHFS error: "s, ## args);\
5086+ } while(0)
5087+
5088+#define WARNING(s, args...) printk(KERN_WARNING "SQUASHFS: "s, ## args)
5089+
5090+static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode)
5091+{
5092+ return list_entry(inode, struct squashfs_inode_info, vfs_inode);
5093+}
5094+
5095+/* block.c */
5096+extern unsigned int squashfs_read_data(struct super_block *, char *,
5097+ long long, unsigned int, long long *, int);
5098+extern int squashfs_get_cached_block(struct super_block *, void *,
5099+ long long, unsigned int, int, long long *, unsigned int *);
5100+
5101+/* cache.c */
5102+extern struct squashfs_cache_entry *squashfs_cache_get(struct super_block *,
5103+ struct squashfs_cache *, long long, int);
5104+extern void squashfs_cache_put(struct squashfs_cache *,
5105+ struct squashfs_cache_entry *);
5106+extern void squashfs_cache_delete(struct squashfs_cache *);
5107+extern struct squashfs_cache *squashfs_cache_init(char *, int, int, int);
5108+
5109+/* export.c */
5110+extern int read_inode_lookup_table(struct super_block *);
5111+
5112+/* file.c */
5113+extern long long read_blocklist(struct inode *, int, int, char *,
5114+ unsigned short **, unsigned int *);
5115+
5116+/* fragment.c */
5117+extern int get_fragment_location(struct super_block *, unsigned int,
5118+ long long *, unsigned int *);
5119+extern void release_cached_fragment(struct squashfs_sb_info *,
5120+ struct squashfs_cache_entry *);
5121+extern struct squashfs_cache_entry *get_cached_fragment(struct super_block *,
5122+ long long, int);
5123+extern int read_fragment_index_table(struct super_block *);
5124+
5125+/* id.c */
5126+extern int get_id(struct super_block *, unsigned int, unsigned int *);
5127+extern int read_id_index_table(struct super_block *);
5128+
5129+/* inode.c */
5130+extern struct inode *squashfs_iget(struct super_block *, squashfs_inode_t,
5131+ unsigned int);
5132+extern int squashfs_read_inode(struct inode *, squashfs_inode_t);
5133+
5134+/*
5135+ * Inodes and files operations
5136+ */
5137+
5138+/* dir.c */
5139+extern const struct file_operations squashfs_dir_ops;
5140+
5141+/* export.c */
5142+extern const struct export_operations squashfs_export_ops;
5143+
5144+/* file.c */
5145+extern const struct address_space_operations squashfs_aops;
5146+
5147+/* namei.c */
5148+extern const struct inode_operations squashfs_dir_inode_ops;
5149+
5150+/* symlink.c */
5151+extern const struct address_space_operations squashfs_symlink_aops;
5152+
5153+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
5154+extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk);
5155+#else
5156+static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk)
5157+{
5158+ return 0;
5159+}
5160+#endif
5161+
5162+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
5163+extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk);
5164+#else
5165+static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
5166+{
5167+ return 0;
5168+}
5169+#endif
5170diff -uNr a/fs/squashfs/super.c b/fs/squashfs/super.c
5171--- a/fs/squashfs/super.c 1969-12-31 16:00:00.000000000 -0800
5172+++ b/fs/squashfs/super.c 2008-08-13 16:14:50.000000000 -0700
5173@@ -0,0 +1,381 @@
5174+/*
5175+ * Squashfs - a compressed read only filesystem for Linux
5176+ *
5177+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5178+ * Phillip Lougher <phillip@lougher.demon.co.uk>
5179+ *
5180+ * This program is free software; you can redistribute it and/or
5181+ * modify it under the terms of the GNU General Public License
5182+ * as published by the Free Software Foundation; either version 2,
5183+ * or (at your option) any later version.
5184+ *
5185+ * This program is distributed in the hope that it will be useful,
5186+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5187+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5188+ * GNU General Public License for more details.
5189+ *
5190+ * You should have received a copy of the GNU General Public License
5191+ * along with this program; if not, write to the Free Software
5192+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5193+ *
5194+ * super.c
5195+ */
5196+
5197+#include <linux/squashfs_fs.h>
5198+#include <linux/module.h>
5199+#include <linux/zlib.h>
5200+#include <linux/fs.h>
5201+#include <linux/squashfs_fs_sb.h>
5202+#include <linux/squashfs_fs_i.h>
5203+#include <linux/buffer_head.h>
5204+#include <linux/vfs.h>
5205+#include <linux/vmalloc.h>
5206+#include <linux/spinlock.h>
5207+#include <linux/smp_lock.h>
5208+#include <linux/exportfs.h>
5209+
5210+#include "squashfs.h"
5211+
5212+static struct file_system_type squashfs_fs_type;
5213+static struct super_operations squashfs_super_ops;
5214+
5215+static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent)
5216+{
5217+ struct squashfs_super_block *sblk = &msblk->sblk;
5218+
5219+ msblk->read_inode = squashfs_read_inode;
5220+ msblk->read_blocklist = read_blocklist;
5221+ msblk->read_fragment_index_table = read_fragment_index_table;
5222+
5223+ if (sblk->s_major == 1) {
5224+ if (!squashfs_1_0_supported(msblk)) {
5225+ SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems "
5226+ "are unsupported\n");
5227+ SERROR("Please recompile with Squashfs 1.0 support enabled\n");
5228+ return 0;
5229+ }
5230+ } else if (sblk->s_major == 2) {
5231+ if (!squashfs_2_0_supported(msblk)) {
5232+ SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems "
5233+ "are unsupported\n");
5234+ SERROR("Please recompile with Squashfs 2.0 support enabled\n");
5235+ return 0;
5236+ }
5237+ } else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor >
5238+ SQUASHFS_MINOR) {
5239+ SERROR("Major/Minor mismatch, trying to mount newer %d.%d "
5240+ "filesystem\n", sblk->s_major, sblk->s_minor);
5241+ SERROR("Please update your kernel\n");
5242+ return 0;
5243+ }
5244+
5245+ return 1;
5246+}
5247+
5248+
5249+static int squashfs_fill_super(struct super_block *s, void *data, int silent)
5250+{
5251+ struct squashfs_sb_info *msblk;
5252+ struct squashfs_super_block *sblk;
5253+ char b[BDEVNAME_SIZE];
5254+ struct inode *root;
5255+
5256+ TRACE("Entered squashfs_fill_superblock\n");
5257+
5258+ s->s_fs_info = kzalloc(sizeof(struct squashfs_sb_info), GFP_KERNEL);
5259+ if (s->s_fs_info == NULL) {
5260+ ERROR("Failed to allocate superblock\n");
5261+ goto failure;
5262+ }
5263+ msblk = s->s_fs_info;
5264+
5265+ msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize());
5266+ if (msblk->stream.workspace == NULL) {
5267+ ERROR("Failed to allocate zlib workspace\n");
5268+ goto failure;
5269+ }
5270+ sblk = &msblk->sblk;
5271+
5272+ msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE);
5273+ msblk->devblksize_log2 = ffz(~msblk->devblksize);
5274+
5275+ mutex_init(&msblk->read_data_mutex);
5276+ mutex_init(&msblk->read_page_mutex);
5277+ mutex_init(&msblk->meta_index_mutex);
5278+
5279+ /* sblk->bytes_used is checked in squashfs_read_data to ensure reads are not
5280+ * beyond filesystem end. As we're using squashfs_read_data to read sblk here,
5281+ * first set sblk->bytes_used to a useful value */
5282+ sblk->bytes_used = sizeof(struct squashfs_super_block);
5283+ if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START,
5284+ sizeof(struct squashfs_super_block) |
5285+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, sizeof(struct squashfs_super_block))) {
5286+ SERROR("unable to read superblock\n");
5287+ goto failed_mount;
5288+ }
5289+
5290+ /* Check it is a SQUASHFS superblock */
5291+ if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) {
5292+ if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) {
5293+ struct squashfs_super_block ssblk;
5294+
5295+ WARNING("Mounting a different endian SQUASHFS filesystem on %s\n",
5296+ bdevname(s->s_bdev, b));
5297+
5298+ //SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk);
5299+ memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block));
5300+ msblk->swap = 1;
5301+ } else {
5302+ SERROR("Can't find a SQUASHFS superblock on %s\n",
5303+ bdevname(s->s_bdev, b));
5304+ goto failed_mount;
5305+ }
5306+ }
5307+
5308+ /* Check the MAJOR & MINOR versions */
5309+ if(!supported_squashfs_filesystem(msblk, silent))
5310+ goto failed_mount;
5311+
5312+ /* Check the filesystem does not extend beyond the end of the
5313+ block device */
5314+ if(sblk->bytes_used < 0 || sblk->bytes_used > i_size_read(s->s_bdev->bd_inode))
5315+ goto failed_mount;
5316+
5317+ /* Check the root inode for sanity */
5318+ if (SQUASHFS_INODE_OFFSET(sblk->root_inode) > SQUASHFS_METADATA_SIZE)
5319+ goto failed_mount;
5320+
5321+ TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b));
5322+ TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(sblk->flags)
5323+ ? "un" : "");
5324+ TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(sblk->flags)
5325+ ? "un" : "");
5326+ TRACE("Check data is %spresent in the filesystem\n",
5327+ SQUASHFS_CHECK_DATA(sblk->flags) ? "" : "not ");
5328+ TRACE("Filesystem size %lld bytes\n", sblk->bytes_used);
5329+ TRACE("Block size %d\n", sblk->block_size);
5330+ TRACE("Number of inodes %d\n", sblk->inodes);
5331+ if (sblk->s_major > 1)
5332+ TRACE("Number of fragments %d\n", sblk->fragments);
5333+ TRACE("Number of ids %d\n", sblk->no_ids);
5334+ TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start);
5335+ TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start);
5336+ if (sblk->s_major > 1)
5337+ TRACE("sblk->fragment_table_start %llx\n", sblk->fragment_table_start);
5338+ TRACE("sblk->id_table_start %llx\n", sblk->id_table_start);
5339+
5340+ s->s_maxbytes = MAX_LFS_FILESIZE;
5341+ s->s_flags |= MS_RDONLY;
5342+ s->s_op = &squashfs_super_ops;
5343+
5344+ msblk->block_cache = squashfs_cache_init("metadata", SQUASHFS_CACHED_BLKS,
5345+ SQUASHFS_METADATA_SIZE, 0);
5346+ if (msblk->block_cache == NULL)
5347+ goto failed_mount;
5348+
5349+ /* Allocate read_page block */
5350+ msblk->read_page = vmalloc(sblk->block_size);
5351+ if (msblk->read_page == NULL) {
5352+ ERROR("Failed to allocate read_page block\n");
5353+ goto failed_mount;
5354+ }
5355+
5356+ /* Allocate and read id index table */
5357+ if (read_id_index_table(s) == 0)
5358+ goto failed_mount;
5359+
5360+ if (sblk->s_major == 1 && squashfs_1_0_supported(msblk))
5361+ goto allocate_root;
5362+
5363+ msblk->fragment_cache = squashfs_cache_init("fragment",
5364+ SQUASHFS_CACHED_FRAGMENTS, sblk->block_size, 1);
5365+ if (msblk->fragment_cache == NULL)
5366+ goto failed_mount;
5367+
5368+ /* Allocate and read fragment index table */
5369+ if (msblk->read_fragment_index_table(s) == 0)
5370+ goto failed_mount;
5371+
5372+ if(sblk->s_major < 3 || sblk->lookup_table_start == SQUASHFS_INVALID_BLK)
5373+ goto allocate_root;
5374+
5375+ /* Allocate and read inode lookup table */
5376+ if (read_inode_lookup_table(s) == 0)
5377+ goto failed_mount;
5378+
5379+ s->s_export_op = &squashfs_export_ops;
5380+
5381+allocate_root:
5382+ root = new_inode(s);
5383+ if ((msblk->read_inode)(root, sblk->root_inode) == 0)
5384+ goto failed_mount;
5385+ insert_inode_hash(root);
5386+
5387+ s->s_root = d_alloc_root(root);
5388+ if (s->s_root == NULL) {
5389+ ERROR("Root inode create failed\n");
5390+ iput(root);
5391+ goto failed_mount;
5392+ }
5393+
5394+ TRACE("Leaving squashfs_fill_super\n");
5395+ return 0;
5396+
5397+failed_mount:
5398+ kfree(msblk->inode_lookup_table);
5399+ kfree(msblk->fragment_index);
5400+ squashfs_cache_delete(msblk->fragment_cache);
5401+ kfree(msblk->id_table);
5402+ vfree(msblk->read_page);
5403+ squashfs_cache_delete(msblk->block_cache);
5404+ kfree(msblk->fragment_index_2);
5405+ vfree(msblk->stream.workspace);
5406+ kfree(s->s_fs_info);
5407+ s->s_fs_info = NULL;
5408+ return -EINVAL;
5409+
5410+failure:
5411+ return -ENOMEM;
5412+}
5413+
5414+
5415+static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
5416+{
5417+ struct squashfs_sb_info *msblk = dentry->d_sb->s_fs_info;
5418+ struct squashfs_super_block *sblk = &msblk->sblk;
5419+
5420+ TRACE("Entered squashfs_statfs\n");
5421+
5422+ buf->f_type = SQUASHFS_MAGIC;
5423+ buf->f_bsize = sblk->block_size;
5424+ buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1;
5425+ buf->f_bfree = buf->f_bavail = 0;
5426+ buf->f_files = sblk->inodes;
5427+ buf->f_ffree = 0;
5428+ buf->f_namelen = SQUASHFS_NAME_LEN;
5429+
5430+ return 0;
5431+}
5432+
5433+
5434+static int squashfs_remount(struct super_block *s, int *flags, char *data)
5435+{
5436+ *flags |= MS_RDONLY;
5437+ return 0;
5438+}
5439+
5440+
5441+static void squashfs_put_super(struct super_block *s)
5442+{
5443+ if (s->s_fs_info) {
5444+ struct squashfs_sb_info *sbi = s->s_fs_info;
5445+ squashfs_cache_delete(sbi->block_cache);
5446+ squashfs_cache_delete(sbi->fragment_cache);
5447+ vfree(sbi->read_page);
5448+ kfree(sbi->id_table);
5449+ kfree(sbi->fragment_index);
5450+ kfree(sbi->fragment_index_2);
5451+ kfree(sbi->meta_index);
5452+ vfree(sbi->stream.workspace);
5453+ kfree(s->s_fs_info);
5454+ s->s_fs_info = NULL;
5455+ }
5456+}
5457+
5458+
5459+static int squashfs_get_sb(struct file_system_type *fs_type, int flags,
5460+ const char *dev_name, void *data, struct vfsmount *mnt)
5461+{
5462+ return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super,
5463+ mnt);
5464+}
5465+
5466+
5467+static struct kmem_cache * squashfs_inode_cachep;
5468+
5469+
5470+static void init_once(void *foo)
5471+{
5472+ struct squashfs_inode_info *ei = foo;
5473+
5474+ inode_init_once(&ei->vfs_inode);
5475+}
5476+
5477+
5478+static int __init init_inodecache(void)
5479+{
5480+ squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache",
5481+ sizeof(struct squashfs_inode_info), 0,
5482+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, init_once);
5483+ if (squashfs_inode_cachep == NULL)
5484+ return -ENOMEM;
5485+ return 0;
5486+}
5487+
5488+
5489+static void destroy_inodecache(void)
5490+{
5491+ kmem_cache_destroy(squashfs_inode_cachep);
5492+}
5493+
5494+
5495+static int __init init_squashfs_fs(void)
5496+{
5497+ int err = init_inodecache();
5498+ if (err)
5499+ goto out;
5500+
5501+ printk(KERN_INFO "squashfs: version 4.0-CVS (2008/07/27) "
5502+ "Phillip Lougher\n");
5503+
5504+ err = register_filesystem(&squashfs_fs_type);
5505+ if (err)
5506+ destroy_inodecache();
5507+
5508+out:
5509+ return err;
5510+}
5511+
5512+
5513+static void __exit exit_squashfs_fs(void)
5514+{
5515+ unregister_filesystem(&squashfs_fs_type);
5516+ destroy_inodecache();
5517+}
5518+
5519+
5520+static struct inode *squashfs_alloc_inode(struct super_block *sb)
5521+{
5522+ struct squashfs_inode_info *ei;
5523+ ei = kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL);
5524+ return ei ? &ei->vfs_inode : NULL;
5525+}
5526+
5527+
5528+static void squashfs_destroy_inode(struct inode *inode)
5529+{
5530+ kmem_cache_free(squashfs_inode_cachep, SQUASHFS_I(inode));
5531+}
5532+
5533+
5534+static struct file_system_type squashfs_fs_type = {
5535+ .owner = THIS_MODULE,
5536+ .name = "squashfs",
5537+ .get_sb = squashfs_get_sb,
5538+ .kill_sb = kill_block_super,
5539+ .fs_flags = FS_REQUIRES_DEV
5540+};
5541+
5542+static struct super_operations squashfs_super_ops = {
5543+ .alloc_inode = squashfs_alloc_inode,
5544+ .destroy_inode = squashfs_destroy_inode,
5545+ .statfs = squashfs_statfs,
5546+ .put_super = squashfs_put_super,
5547+ .remount_fs = squashfs_remount
5548+};
5549+
5550+module_init(init_squashfs_fs);
5551+module_exit(exit_squashfs_fs);
5552+MODULE_DESCRIPTION("squashfs 4.0-CVS, a compressed read-only filesystem");
5553+MODULE_AUTHOR("Phillip Lougher <phillip@lougher.demon.co.uk>");
5554+MODULE_LICENSE("GPL");
5555diff -uNr a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c
5556--- a/fs/squashfs/symlink.c 1969-12-31 16:00:00.000000000 -0800
5557+++ b/fs/squashfs/symlink.c 2008-08-13 16:14:50.000000000 -0700
5558@@ -0,0 +1,85 @@
5559+/*
5560+ * Squashfs - a compressed read only filesystem for Linux
5561+ *
5562+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5563+ * Phillip Lougher <phillip@lougher.demon.co.uk>
5564+ *
5565+ * This program is free software; you can redistribute it and/or
5566+ * modify it under the terms of the GNU General Public License
5567+ * as published by the Free Software Foundation; either version 2,
5568+ * or (at your option) any later version.
5569+ *
5570+ * This program is distributed in the hope that it will be useful,
5571+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5572+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5573+ * GNU General Public License for more details.
5574+ *
5575+ * You should have received a copy of the GNU General Public License
5576+ * along with this program; if not, write to the Free Software
5577+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5578+ *
5579+ * symlink.c
5580+ */
5581+
5582+#include <linux/fs.h>
5583+#include <linux/vfs.h>
5584+#include <linux/zlib.h>
5585+#include <linux/buffer_head.h>
5586+#include <linux/squashfs_fs.h>
5587+#include <linux/squashfs_fs_sb.h>
5588+#include <linux/squashfs_fs_i.h>
5589+
5590+#include "squashfs.h"
5591+
5592+static int squashfs_symlink_readpage(struct file *file, struct page *page)
5593+{
5594+ struct inode *inode = page->mapping->host;
5595+ int index = page->index << PAGE_CACHE_SHIFT;
5596+ long long block = SQUASHFS_I(inode)->start_block;
5597+ int offset = SQUASHFS_I(inode)->offset;
5598+ void *pageaddr = kmap(page);
5599+ int length, bytes, avail_bytes;
5600+
5601+ TRACE("Entered squashfs_symlink_readpage, page index %ld, start block "
5602+ "%llx, offset %x\n", page->index,
5603+ SQUASHFS_I(inode)->start_block,
5604+ SQUASHFS_I(inode)->offset);
5605+
5606+ for (length = 0; length < index; length += bytes) {
5607+ bytes = squashfs_get_cached_block(inode->i_sb, NULL, block,
5608+ offset, PAGE_CACHE_SIZE, &block, &offset);
5609+ if (bytes == 0) {
5610+ ERROR("Unable to read symbolic link [%llx:%x]\n",
5611+ block, offset);
5612+ goto skip_read;
5613+ }
5614+ }
5615+
5616+ if (length != index) {
5617+ ERROR("(squashfs_symlink_readpage) length != index\n");
5618+ bytes = 0;
5619+ goto skip_read;
5620+ }
5621+
5622+ avail_bytes = min_t(int, i_size_read(inode) - length, PAGE_CACHE_SIZE);
5623+
5624+ bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block, offset,
5625+ avail_bytes, &block, &offset);
5626+ if (bytes == 0)
5627+ ERROR("Unable to read symbolic link [%llx:%x]\n", block,
5628+ offset);
5629+
5630+skip_read:
5631+ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
5632+ kunmap(page);
5633+ flush_dcache_page(page);
5634+ SetPageUptodate(page);
5635+ unlock_page(page);
5636+
5637+ return 0;
5638+}
5639+
5640+
5641+const struct address_space_operations squashfs_symlink_aops = {
5642+ .readpage = squashfs_symlink_readpage
5643+};
5644diff -uNr a/include/linux/squashfs_fs.h b/include/linux/squashfs_fs.h
5645--- a/include/linux/squashfs_fs.h 1969-12-31 16:00:00.000000000 -0800
5646+++ b/include/linux/squashfs_fs.h 2008-08-13 16:16:05.000000000 -0700
5647@@ -0,0 +1,949 @@
5648+#ifndef SQUASHFS_FS
5649+#define SQUASHFS_FS
5650+/*
5651+ * Squashfs
5652+ *
5653+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5654+ * Phillip Lougher <phillip@lougher.demon.co.uk>
5655+ *
5656+ * This program is free software; you can redistribute it and/or
5657+ * modify it under the terms of the GNU General Public License
5658+ * as published by the Free Software Foundation; either version 2,
5659+ * or (at your option) any later version.
5660+ *
5661+ * This program is distributed in the hope that it will be useful,
5662+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5663+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5664+ * GNU General Public License for more details.
5665+ *
5666+ * You should have received a copy of the GNU General Public License
5667+ * along with this program; if not, write to the Free Software
5668+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5669+ *
5670+ * squashfs_fs.h
5671+ */
5672+
5673+#if 0
5674+#ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY
5675+#define CONFIG_SQUASHFS_2_0_COMPATIBILITY
5676+#endif
5677+#endif
5678+
5679+#define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE
5680+#define SQUASHFS_MAJOR 4
5681+#define SQUASHFS_MINOR 0
5682+#define SQUASHFS_MAGIC 0x73717368
5683+#define SQUASHFS_MAGIC_SWAP 0x68737173
5684+#define SQUASHFS_START 0
5685+
5686+/* size of metadata (inode and directory) blocks */
5687+#define SQUASHFS_METADATA_SIZE 8192
5688+#define SQUASHFS_METADATA_LOG 13
5689+
5690+/* default size of data blocks */
5691+#define SQUASHFS_FILE_SIZE 131072
5692+#define SQUASHFS_FILE_LOG 17
5693+
5694+#define SQUASHFS_FILE_MAX_SIZE 1048576
5695+
5696+/* Max number of uids and gids */
5697+#define SQUASHFS_IDS 65536
5698+
5699+/* Max length of filename (not 255) */
5700+#define SQUASHFS_NAME_LEN 256
5701+
5702+#define SQUASHFS_INVALID ((long long) 0xffffffffffff)
5703+#define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff)
5704+#define SQUASHFS_INVALID_BLK ((long long) -1)
5705+#define SQUASHFS_USED_BLK ((long long) -2)
5706+
5707+/* Filesystem flags */
5708+#define SQUASHFS_NOI 0
5709+#define SQUASHFS_NOD 1
5710+#define SQUASHFS_CHECK 2
5711+#define SQUASHFS_NOF 3
5712+#define SQUASHFS_NO_FRAG 4
5713+#define SQUASHFS_ALWAYS_FRAG 5
5714+#define SQUASHFS_DUPLICATE 6
5715+#define SQUASHFS_EXPORT 7
5716+
5717+#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1)
5718+
5719+#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \
5720+ SQUASHFS_NOI)
5721+
5722+#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \
5723+ SQUASHFS_NOD)
5724+
5725+#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
5726+ SQUASHFS_NOF)
5727+
5728+#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
5729+ SQUASHFS_NO_FRAG)
5730+
5731+#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
5732+ SQUASHFS_ALWAYS_FRAG)
5733+
5734+#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \
5735+ SQUASHFS_DUPLICATE)
5736+
5737+#define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \
5738+ SQUASHFS_EXPORT)
5739+
5740+#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \
5741+ SQUASHFS_CHECK)
5742+
5743+#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \
5744+ duplicate_checking, exportable) (noi | (nod << 1) | (check_data << 2) \
5745+ | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \
5746+ (duplicate_checking << 6) | (exportable << 7))
5747+
5748+/* Max number of types and file types */
5749+#define SQUASHFS_DIR_TYPE 1
5750+#define SQUASHFS_FILE_TYPE 2
5751+#define SQUASHFS_SYMLINK_TYPE 3
5752+#define SQUASHFS_BLKDEV_TYPE 4
5753+#define SQUASHFS_CHRDEV_TYPE 5
5754+#define SQUASHFS_FIFO_TYPE 6
5755+#define SQUASHFS_SOCKET_TYPE 7
5756+#define SQUASHFS_LDIR_TYPE 8
5757+#define SQUASHFS_LREG_TYPE 9
5758+
5759+/* 1.0 filesystem type definitions */
5760+#define SQUASHFS_TYPES 5
5761+#define SQUASHFS_IPC_TYPE 0
5762+
5763+/* Flag whether block is compressed or uncompressed, bit is set if block is
5764+ * uncompressed */
5765+#define SQUASHFS_COMPRESSED_BIT (1 << 15)
5766+
5767+#define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \
5768+ (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT)
5769+
5770+#define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT))
5771+
5772+#define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24)
5773+
5774+#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) ((B) & \
5775+ ~SQUASHFS_COMPRESSED_BIT_BLOCK)
5776+
5777+#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
5778+
5779+/*
5780+ * Inode number ops. Inodes consist of a compressed block number, and an
5781+ * uncompressed offset within that block
5782+ */
5783+#define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16))
5784+
5785+#define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff))
5786+
5787+#define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\
5788+ << 16) + (B)))
5789+
5790+/* Compute 32 bit VFS inode number from squashfs inode number */
5791+#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \
5792+ ((b) >> 2) + 1))
5793+/* XXX */
5794+
5795+/* Translate between VFS mode and squashfs mode */
5796+#define SQUASHFS_MODE(a) ((a) & 0xfff)
5797+
5798+/* fragment and fragment table defines */
5799+#define SQUASHFS_FRAGMENT_BYTES(A) ((A) * sizeof(struct squashfs_fragment_entry))
5800+
5801+#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \
5802+ SQUASHFS_METADATA_SIZE)
5803+
5804+#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \
5805+ SQUASHFS_METADATA_SIZE)
5806+
5807+#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \
5808+ SQUASHFS_METADATA_SIZE - 1) / \
5809+ SQUASHFS_METADATA_SIZE)
5810+
5811+#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\
5812+ sizeof(long long))
5813+
5814+/* inode lookup table defines */
5815+#define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(squashfs_inode_t))
5816+
5817+#define SQUASHFS_LOOKUP_BLOCK(A) (SQUASHFS_LOOKUP_BYTES(A) / \
5818+ SQUASHFS_METADATA_SIZE)
5819+
5820+#define SQUASHFS_LOOKUP_BLOCK_OFFSET(A) (SQUASHFS_LOOKUP_BYTES(A) % \
5821+ SQUASHFS_METADATA_SIZE)
5822+
5823+#define SQUASHFS_LOOKUP_BLOCKS(A) ((SQUASHFS_LOOKUP_BYTES(A) + \
5824+ SQUASHFS_METADATA_SIZE - 1) / \
5825+ SQUASHFS_METADATA_SIZE)
5826+
5827+#define SQUASHFS_LOOKUP_BLOCK_BYTES(A) (SQUASHFS_LOOKUP_BLOCKS(A) *\
5828+ sizeof(long long))
5829+
5830+/* uid lookup table defines */
5831+#define SQUASHFS_ID_BYTES(A) ((A) * sizeof(unsigned int))
5832+
5833+#define SQUASHFS_ID_BLOCK(A) (SQUASHFS_ID_BYTES(A) / \
5834+ SQUASHFS_METADATA_SIZE)
5835+
5836+#define SQUASHFS_ID_BLOCK_OFFSET(A) (SQUASHFS_ID_BYTES(A) % \
5837+ SQUASHFS_METADATA_SIZE)
5838+
5839+#define SQUASHFS_ID_BLOCKS(A) ((SQUASHFS_ID_BYTES(A) + \
5840+ SQUASHFS_METADATA_SIZE - 1) / \
5841+ SQUASHFS_METADATA_SIZE)
5842+
5843+#define SQUASHFS_ID_BLOCK_BYTES(A) (SQUASHFS_ID_BLOCKS(A) *\
5844+ sizeof(long long))
5845+
5846+/* cached data constants for filesystem */
5847+#define SQUASHFS_CACHED_BLKS 8
5848+
5849+#define SQUASHFS_MAX_FILE_SIZE_LOG 64
5850+
5851+#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \
5852+ (SQUASHFS_MAX_FILE_SIZE_LOG - 2))
5853+
5854+#define SQUASHFS_MARKER_BYTE 0xff
5855+
5856+/* meta index cache */
5857+#define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int))
5858+#define SQUASHFS_META_ENTRIES 31
5859+#define SQUASHFS_META_NUMBER 8
5860+#define SQUASHFS_SLOTS 4
5861+
5862+struct meta_entry {
5863+ long long data_block;
5864+ unsigned int index_block;
5865+ unsigned short offset;
5866+ unsigned short pad;
5867+};
5868+
5869+struct meta_index {
5870+ unsigned int inode_number;
5871+ unsigned int offset;
5872+ unsigned short entries;
5873+ unsigned short skip;
5874+ unsigned short locked;
5875+ unsigned short pad;
5876+ struct meta_entry meta_entry[SQUASHFS_META_ENTRIES];
5877+};
5878+
5879+
5880+/*
5881+ * definitions for structures on disk
5882+ */
5883+
5884+typedef long long squashfs_block_t;
5885+typedef long long squashfs_inode_t;
5886+
5887+#define COMPRESSION_ZLIB 1
5888+
5889+struct squashfs_super_block {
5890+ unsigned int s_magic;
5891+ unsigned int inodes;
5892+ unsigned int mkfs_time /* time of filesystem creation */;
5893+ unsigned int block_size;
5894+ unsigned int fragments;
5895+ unsigned short compression;
5896+ unsigned short block_log;
5897+ unsigned short flags;
5898+ unsigned short no_ids;
5899+ unsigned short s_major;
5900+ unsigned short s_minor;
5901+ squashfs_inode_t root_inode;
5902+ long long bytes_used;
5903+ long long id_table_start;
5904+ long long xattr_table_start;
5905+ long long inode_table_start;
5906+ long long directory_table_start;
5907+ long long fragment_table_start;
5908+ long long lookup_table_start;
5909+};
5910+
5911+struct squashfs_dir_index {
5912+ unsigned int index;
5913+ unsigned int start_block;
5914+ unsigned int size;
5915+ unsigned char name[0];
5916+};
5917+
5918+#define SQUASHFS_BASE_INODE_HEADER \
5919+ unsigned short inode_type; \
5920+ unsigned short mode; \
5921+ unsigned short uid; \
5922+ unsigned short guid; \
5923+ unsigned int mtime; \
5924+ unsigned int inode_number;
5925+
5926+struct squashfs_base_inode_header {
5927+ SQUASHFS_BASE_INODE_HEADER;
5928+};
5929+
5930+struct squashfs_ipc_inode_header {
5931+ SQUASHFS_BASE_INODE_HEADER;
5932+ unsigned int nlink;
5933+};
5934+
5935+struct squashfs_dev_inode_header {
5936+ SQUASHFS_BASE_INODE_HEADER;
5937+ unsigned int nlink;
5938+ unsigned int rdev;
5939+};
5940+
5941+struct squashfs_symlink_inode_header {
5942+ SQUASHFS_BASE_INODE_HEADER;
5943+ unsigned int nlink;
5944+ unsigned int symlink_size;
5945+ char symlink[0];
5946+};
5947+
5948+struct squashfs_reg_inode_header {
5949+ SQUASHFS_BASE_INODE_HEADER;
5950+ unsigned int start_block;
5951+ unsigned int fragment;
5952+ unsigned int offset;
5953+ unsigned int file_size;
5954+ unsigned short block_list[0];
5955+};
5956+
5957+struct squashfs_lreg_inode_header {
5958+ SQUASHFS_BASE_INODE_HEADER;
5959+ squashfs_block_t start_block;
5960+ long long file_size;
5961+ long long sparse;
5962+ unsigned int nlink;
5963+ unsigned int fragment;
5964+ unsigned int offset;
5965+ unsigned int xattr;
5966+ unsigned short block_list[0];
5967+};
5968+
5969+struct squashfs_dir_inode_header {
5970+ SQUASHFS_BASE_INODE_HEADER;
5971+ unsigned int start_block;
5972+ unsigned int nlink;
5973+ unsigned short file_size;
5974+ unsigned short offset;
5975+ unsigned int parent_inode;
5976+};
5977+
5978+struct squashfs_ldir_inode_header {
5979+ SQUASHFS_BASE_INODE_HEADER;
5980+ unsigned int nlink;
5981+ unsigned int file_size;
5982+ unsigned int start_block;
5983+ unsigned int parent_inode;
5984+ unsigned short i_count;
5985+ unsigned short offset;
5986+ struct squashfs_dir_index index[0];
5987+};
5988+
5989+union squashfs_inode_header {
5990+ struct squashfs_base_inode_header base;
5991+ struct squashfs_dev_inode_header dev;
5992+ struct squashfs_symlink_inode_header symlink;
5993+ struct squashfs_reg_inode_header reg;
5994+ struct squashfs_lreg_inode_header lreg;
5995+ struct squashfs_dir_inode_header dir;
5996+ struct squashfs_ldir_inode_header ldir;
5997+ struct squashfs_ipc_inode_header ipc;
5998+};
5999+
6000+struct squashfs_dir_entry {
6001+ unsigned short offset;
6002+ short inode_number;
6003+ unsigned short type;
6004+ unsigned short size;
6005+ char name[0];
6006+};
6007+
6008+struct squashfs_dir_header {
6009+ unsigned int count;
6010+ unsigned int start_block;
6011+ unsigned int inode_number;
6012+};
6013+
6014+struct squashfs_fragment_entry {
6015+ long long start_block;
6016+ unsigned int size;
6017+ unsigned int unused;
6018+};
6019+
6020+extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen);
6021+extern int squashfs_uncompress_init(void);
6022+extern int squashfs_uncompress_exit(void);
6023+
6024+/*
6025+ * macros to convert each packed bitfield structure from little endian to big
6026+ * endian and vice versa. These are needed when creating or using a filesystem
6027+ * on a machine with different byte ordering to the target architecture.
6028+ *
6029+ */
6030+
6031+#define SQUASHFS_SWAP_START \
6032+ int bits;\
6033+ int b_pos;\
6034+ unsigned long long val;\
6035+ unsigned char *s;\
6036+ unsigned char *d;
6037+
6038+#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\
6039+ SQUASHFS_SWAP_START\
6040+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\
6041+ SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\
6042+ SQUASHFS_SWAP((s)->inodes, d, 32, 32);\
6043+ SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\
6044+ SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\
6045+ SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\
6046+ SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\
6047+ SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\
6048+ SQUASHFS_SWAP((s)->s_major, d, 224, 16);\
6049+ SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\
6050+ SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\
6051+ SQUASHFS_SWAP((s)->block_log, d, 272, 16);\
6052+ SQUASHFS_SWAP((s)->flags, d, 288, 8);\
6053+ SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\
6054+ SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\
6055+ SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\
6056+ SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\
6057+ SQUASHFS_SWAP((s)->block_size, d, 408, 32);\
6058+ SQUASHFS_SWAP((s)->fragments, d, 440, 32);\
6059+ SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\
6060+ SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\
6061+ SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\
6062+ SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\
6063+ SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\
6064+ SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\
6065+ SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\
6066+ SQUASHFS_SWAP((s)->lookup_table_start, d, 888, 64);\
6067+}
6068+
6069+#define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
6070+ SQUASHFS_MEMSET(s, d, n);\
6071+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
6072+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
6073+ SQUASHFS_SWAP((s)->uid, d, 16, 8);\
6074+ SQUASHFS_SWAP((s)->guid, d, 24, 8);\
6075+ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
6076+ SQUASHFS_SWAP((s)->inode_number, d, 64, 32);
6077+
6078+#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\
6079+ SQUASHFS_SWAP_START\
6080+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
6081+}
6082+
6083+#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\
6084+ SQUASHFS_SWAP_START\
6085+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6086+ sizeof(struct squashfs_ipc_inode_header))\
6087+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6088+}
6089+
6090+#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\
6091+ SQUASHFS_SWAP_START\
6092+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6093+ sizeof(struct squashfs_dev_inode_header)); \
6094+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6095+ SQUASHFS_SWAP((s)->rdev, d, 128, 16);\
6096+}
6097+
6098+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\
6099+ SQUASHFS_SWAP_START\
6100+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6101+ sizeof(struct squashfs_symlink_inode_header));\
6102+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6103+ SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\
6104+}
6105+
6106+#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\
6107+ SQUASHFS_SWAP_START\
6108+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6109+ sizeof(struct squashfs_reg_inode_header));\
6110+ SQUASHFS_SWAP((s)->start_block, d, 96, 64);\
6111+ SQUASHFS_SWAP((s)->fragment, d, 160, 32);\
6112+ SQUASHFS_SWAP((s)->offset, d, 192, 32);\
6113+ SQUASHFS_SWAP((s)->file_size, d, 224, 32);\
6114+}
6115+
6116+#define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\
6117+ SQUASHFS_SWAP_START\
6118+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6119+ sizeof(struct squashfs_lreg_inode_header));\
6120+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6121+ SQUASHFS_SWAP((s)->start_block, d, 128, 64);\
6122+ SQUASHFS_SWAP((s)->fragment, d, 192, 32);\
6123+ SQUASHFS_SWAP((s)->offset, d, 224, 32);\
6124+ SQUASHFS_SWAP((s)->file_size, d, 256, 64);\
6125+}
6126+
6127+#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\
6128+ SQUASHFS_SWAP_START\
6129+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6130+ sizeof(struct squashfs_dir_inode_header));\
6131+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6132+ SQUASHFS_SWAP((s)->file_size, d, 128, 19);\
6133+ SQUASHFS_SWAP((s)->offset, d, 147, 13);\
6134+ SQUASHFS_SWAP((s)->start_block, d, 160, 32);\
6135+ SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\
6136+}
6137+
6138+#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\
6139+ SQUASHFS_SWAP_START\
6140+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6141+ sizeof(struct squashfs_ldir_inode_header));\
6142+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6143+ SQUASHFS_SWAP((s)->file_size, d, 128, 27);\
6144+ SQUASHFS_SWAP((s)->offset, d, 155, 13);\
6145+ SQUASHFS_SWAP((s)->start_block, d, 168, 32);\
6146+ SQUASHFS_SWAP((s)->i_count, d, 200, 16);\
6147+ SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\
6148+}
6149+
6150+#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\
6151+ SQUASHFS_SWAP_START\
6152+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\
6153+ SQUASHFS_SWAP((s)->index, d, 0, 32);\
6154+ SQUASHFS_SWAP((s)->start_block, d, 32, 32);\
6155+ SQUASHFS_SWAP((s)->size, d, 64, 8);\
6156+}
6157+
6158+#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\
6159+ SQUASHFS_SWAP_START\
6160+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\
6161+ SQUASHFS_SWAP((s)->count, d, 0, 8);\
6162+ SQUASHFS_SWAP((s)->start_block, d, 8, 32);\
6163+ SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\
6164+}
6165+
6166+#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\
6167+ SQUASHFS_SWAP_START\
6168+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\
6169+ SQUASHFS_SWAP((s)->offset, d, 0, 13);\
6170+ SQUASHFS_SWAP((s)->type, d, 13, 3);\
6171+ SQUASHFS_SWAP((s)->size, d, 16, 8);\
6172+ SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\
6173+}
6174+
6175+#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\
6176+ SQUASHFS_SWAP_START\
6177+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\
6178+ SQUASHFS_SWAP((s)->start_block, d, 0, 64);\
6179+ SQUASHFS_SWAP((s)->size, d, 64, 32);\
6180+}
6181+
6182+#define SQUASHFS_SWAP_INODE_T(s, d) SQUASHFS_SWAP_LONG_LONGS(s, d, 1)
6183+
6184+#define SQUASHFS_SWAP_SHORTS(s, d, n) {\
6185+ int entry;\
6186+ int bit_position;\
6187+ SQUASHFS_SWAP_START\
6188+ SQUASHFS_MEMSET(s, d, n * 2);\
6189+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
6190+ 16)\
6191+ SQUASHFS_SWAP(s[entry], d, bit_position, 16);\
6192+}
6193+
6194+#define SQUASHFS_SWAP_INTS(s, d, n) {\
6195+ int entry;\
6196+ int bit_position;\
6197+ SQUASHFS_SWAP_START\
6198+ SQUASHFS_MEMSET(s, d, n * 4);\
6199+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
6200+ 32)\
6201+ SQUASHFS_SWAP(s[entry], d, bit_position, 32);\
6202+}
6203+
6204+#define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\
6205+ int entry;\
6206+ int bit_position;\
6207+ SQUASHFS_SWAP_START\
6208+ SQUASHFS_MEMSET(s, d, n * 8);\
6209+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
6210+ 64)\
6211+ SQUASHFS_SWAP(s[entry], d, bit_position, 64);\
6212+}
6213+
6214+#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\
6215+ int entry;\
6216+ int bit_position;\
6217+ SQUASHFS_SWAP_START\
6218+ SQUASHFS_MEMSET(s, d, n * bits / 8);\
6219+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
6220+ bits)\
6221+ SQUASHFS_SWAP(s[entry], d, bit_position, bits);\
6222+}
6223+
6224+#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
6225+#define SQUASHFS_SWAP_LOOKUP_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
6226+#define SQUASHFS_SWAP_ID_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
6227+
6228+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
6229+
6230+struct squashfs_base_inode_header_1 {
6231+ unsigned int inode_type:4;
6232+ unsigned int mode:12; /* protection */
6233+ unsigned int uid:4; /* index into uid table */
6234+ unsigned int guid:4; /* index into guid table */
6235+} __attribute__ ((packed));
6236+
6237+struct squashfs_ipc_inode_header_1 {
6238+ unsigned int inode_type:4;
6239+ unsigned int mode:12; /* protection */
6240+ unsigned int uid:4; /* index into uid table */
6241+ unsigned int guid:4; /* index into guid table */
6242+ unsigned int type:4;
6243+ unsigned int offset:4;
6244+} __attribute__ ((packed));
6245+
6246+struct squashfs_dev_inode_header_1 {
6247+ unsigned int inode_type:4;
6248+ unsigned int mode:12; /* protection */
6249+ unsigned int uid:4; /* index into uid table */
6250+ unsigned int guid:4; /* index into guid table */
6251+ unsigned short rdev;
6252+} __attribute__ ((packed));
6253+
6254+struct squashfs_symlink_inode_header_1 {
6255+ unsigned int inode_type:4;
6256+ unsigned int mode:12; /* protection */
6257+ unsigned int uid:4; /* index into uid table */
6258+ unsigned int guid:4; /* index into guid table */
6259+ unsigned short symlink_size;
6260+ char symlink[0];
6261+} __attribute__ ((packed));
6262+
6263+struct squashfs_reg_inode_header_1 {
6264+ unsigned int inode_type:4;
6265+ unsigned int mode:12; /* protection */
6266+ unsigned int uid:4; /* index into uid table */
6267+ unsigned int guid:4; /* index into guid table */
6268+ unsigned int mtime;
6269+ unsigned int start_block;
6270+ unsigned int file_size:32;
6271+ unsigned short block_list[0];
6272+} __attribute__ ((packed));
6273+
6274+struct squashfs_dir_inode_header_1 {
6275+ unsigned int inode_type:4;
6276+ unsigned int mode:12; /* protection */
6277+ unsigned int uid:4; /* index into uid table */
6278+ unsigned int guid:4; /* index into guid table */
6279+ unsigned int file_size:19;
6280+ unsigned int offset:13;
6281+ unsigned int mtime;
6282+ unsigned int start_block:24;
6283+} __attribute__ ((packed));
6284+
6285+union squashfs_inode_header_1 {
6286+ struct squashfs_base_inode_header_1 base;
6287+ struct squashfs_dev_inode_header_1 dev;
6288+ struct squashfs_symlink_inode_header_1 symlink;
6289+ struct squashfs_reg_inode_header_1 reg;
6290+ struct squashfs_dir_inode_header_1 dir;
6291+ struct squashfs_ipc_inode_header_1 ipc;
6292+};
6293+
6294+#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \
6295+ SQUASHFS_MEMSET(s, d, n);\
6296+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
6297+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
6298+ SQUASHFS_SWAP((s)->uid, d, 16, 4);\
6299+ SQUASHFS_SWAP((s)->guid, d, 20, 4);
6300+
6301+#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\
6302+ SQUASHFS_SWAP_START\
6303+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\
6304+}
6305+
6306+#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\
6307+ SQUASHFS_SWAP_START\
6308+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6309+ sizeof(struct squashfs_ipc_inode_header_1));\
6310+ SQUASHFS_SWAP((s)->type, d, 24, 4);\
6311+ SQUASHFS_SWAP((s)->offset, d, 28, 4);\
6312+}
6313+
6314+#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\
6315+ SQUASHFS_SWAP_START\
6316+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6317+ sizeof(struct squashfs_dev_inode_header_1));\
6318+ SQUASHFS_SWAP((s)->rdev, d, 24, 16);\
6319+}
6320+
6321+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\
6322+ SQUASHFS_SWAP_START\
6323+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6324+ sizeof(struct squashfs_symlink_inode_header_1));\
6325+ SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\
6326+}
6327+
6328+#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\
6329+ SQUASHFS_SWAP_START\
6330+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6331+ sizeof(struct squashfs_reg_inode_header_1));\
6332+ SQUASHFS_SWAP((s)->mtime, d, 24, 32);\
6333+ SQUASHFS_SWAP((s)->start_block, d, 56, 32);\
6334+ SQUASHFS_SWAP((s)->file_size, d, 88, 32);\
6335+}
6336+
6337+#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\
6338+ SQUASHFS_SWAP_START\
6339+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6340+ sizeof(struct squashfs_dir_inode_header_1));\
6341+ SQUASHFS_SWAP((s)->file_size, d, 24, 19);\
6342+ SQUASHFS_SWAP((s)->offset, d, 43, 13);\
6343+ SQUASHFS_SWAP((s)->mtime, d, 56, 32);\
6344+ SQUASHFS_SWAP((s)->start_block, d, 88, 24);\
6345+}
6346+
6347+#endif
6348+
6349+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
6350+
6351+struct squashfs_dir_index_2 {
6352+ unsigned int index:27;
6353+ unsigned int start_block:29;
6354+ unsigned char size;
6355+ unsigned char name[0];
6356+} __attribute__ ((packed));
6357+
6358+struct squashfs_base_inode_header_2 {
6359+ unsigned int inode_type:4;
6360+ unsigned int mode:12; /* protection */
6361+ unsigned int uid:8; /* index into uid table */
6362+ unsigned int guid:8; /* index into guid table */
6363+} __attribute__ ((packed));
6364+
6365+struct squashfs_ipc_inode_header_2 {
6366+ unsigned int inode_type:4;
6367+ unsigned int mode:12; /* protection */
6368+ unsigned int uid:8; /* index into uid table */
6369+ unsigned int guid:8; /* index into guid table */
6370+} __attribute__ ((packed));
6371+
6372+struct squashfs_dev_inode_header_2 {
6373+ unsigned int inode_type:4;
6374+ unsigned int mode:12; /* protection */
6375+ unsigned int uid:8; /* index into uid table */
6376+ unsigned int guid:8; /* index into guid table */
6377+ unsigned short rdev;
6378+} __attribute__ ((packed));
6379+
6380+struct squashfs_symlink_inode_header_2 {
6381+ unsigned int inode_type:4;
6382+ unsigned int mode:12; /* protection */
6383+ unsigned int uid:8; /* index into uid table */
6384+ unsigned int guid:8; /* index into guid table */
6385+ unsigned short symlink_size;
6386+ char symlink[0];
6387+} __attribute__ ((packed));
6388+
6389+struct squashfs_reg_inode_header_2 {
6390+ unsigned int inode_type:4;
6391+ unsigned int mode:12; /* protection */
6392+ unsigned int uid:8; /* index into uid table */
6393+ unsigned int guid:8; /* index into guid table */
6394+ unsigned int mtime;
6395+ unsigned int start_block;
6396+ unsigned int fragment;
6397+ unsigned int offset;
6398+ unsigned int file_size:32;
6399+ unsigned short block_list[0];
6400+} __attribute__ ((packed));
6401+
6402+struct squashfs_dir_inode_header_2 {
6403+ unsigned int inode_type:4;
6404+ unsigned int mode:12; /* protection */
6405+ unsigned int uid:8; /* index into uid table */
6406+ unsigned int guid:8; /* index into guid table */
6407+ unsigned int file_size:19;
6408+ unsigned int offset:13;
6409+ unsigned int mtime;
6410+ unsigned int start_block:24;
6411+} __attribute__ ((packed));
6412+
6413+struct squashfs_ldir_inode_header_2 {
6414+ unsigned int inode_type:4;
6415+ unsigned int mode:12; /* protection */
6416+ unsigned int uid:8; /* index into uid table */
6417+ unsigned int guid:8; /* index into guid table */
6418+ unsigned int file_size:27;
6419+ unsigned int offset:13;
6420+ unsigned int mtime;
6421+ unsigned int start_block:24;
6422+ unsigned int i_count:16;
6423+ struct squashfs_dir_index_2 index[0];
6424+} __attribute__ ((packed));
6425+
6426+union squashfs_inode_header_2 {
6427+ struct squashfs_base_inode_header_2 base;
6428+ struct squashfs_dev_inode_header_2 dev;
6429+ struct squashfs_symlink_inode_header_2 symlink;
6430+ struct squashfs_reg_inode_header_2 reg;
6431+ struct squashfs_dir_inode_header_2 dir;
6432+ struct squashfs_ldir_inode_header_2 ldir;
6433+ struct squashfs_ipc_inode_header_2 ipc;
6434+};
6435+
6436+struct squashfs_dir_header_2 {
6437+ unsigned int count:8;
6438+ unsigned int start_block:24;
6439+} __attribute__ ((packed));
6440+
6441+struct squashfs_dir_entry_2 {
6442+ unsigned int offset:13;
6443+ unsigned int type:3;
6444+ unsigned int size:8;
6445+ char name[0];
6446+} __attribute__ ((packed));
6447+
6448+struct squashfs_fragment_entry_2 {
6449+ unsigned int start_block;
6450+ unsigned int size;
6451+} __attribute__ ((packed));
6452+
6453+#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
6454+ SQUASHFS_MEMSET(s, d, n);\
6455+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
6456+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
6457+ SQUASHFS_SWAP((s)->uid, d, 16, 8);\
6458+ SQUASHFS_SWAP((s)->guid, d, 24, 8);\
6459+
6460+#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\
6461+ SQUASHFS_SWAP_START\
6462+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
6463+}
6464+
6465+#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \
6466+ SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2))
6467+
6468+#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\
6469+ SQUASHFS_SWAP_START\
6470+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6471+ sizeof(struct squashfs_dev_inode_header_2)); \
6472+ SQUASHFS_SWAP((s)->rdev, d, 32, 16);\
6473+}
6474+
6475+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\
6476+ SQUASHFS_SWAP_START\
6477+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6478+ sizeof(struct squashfs_symlink_inode_header_2));\
6479+ SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\
6480+}
6481+
6482+#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\
6483+ SQUASHFS_SWAP_START\
6484+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6485+ sizeof(struct squashfs_reg_inode_header_2));\
6486+ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
6487+ SQUASHFS_SWAP((s)->start_block, d, 64, 32);\
6488+ SQUASHFS_SWAP((s)->fragment, d, 96, 32);\
6489+ SQUASHFS_SWAP((s)->offset, d, 128, 32);\
6490+ SQUASHFS_SWAP((s)->file_size, d, 160, 32);\
6491+}
6492+
6493+#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\
6494+ SQUASHFS_SWAP_START\
6495+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6496+ sizeof(struct squashfs_dir_inode_header_2));\
6497+ SQUASHFS_SWAP((s)->file_size, d, 32, 19);\
6498+ SQUASHFS_SWAP((s)->offset, d, 51, 13);\
6499+ SQUASHFS_SWAP((s)->mtime, d, 64, 32);\
6500+ SQUASHFS_SWAP((s)->start_block, d, 96, 24);\
6501+}
6502+
6503+#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\
6504+ SQUASHFS_SWAP_START\
6505+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6506+ sizeof(struct squashfs_ldir_inode_header_2));\
6507+ SQUASHFS_SWAP((s)->file_size, d, 32, 27);\
6508+ SQUASHFS_SWAP((s)->offset, d, 59, 13);\
6509+ SQUASHFS_SWAP((s)->mtime, d, 72, 32);\
6510+ SQUASHFS_SWAP((s)->start_block, d, 104, 24);\
6511+ SQUASHFS_SWAP((s)->i_count, d, 128, 16);\
6512+}
6513+
6514+#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\
6515+ SQUASHFS_SWAP_START\
6516+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\
6517+ SQUASHFS_SWAP((s)->index, d, 0, 27);\
6518+ SQUASHFS_SWAP((s)->start_block, d, 27, 29);\
6519+ SQUASHFS_SWAP((s)->size, d, 56, 8);\
6520+}
6521+#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\
6522+ SQUASHFS_SWAP_START\
6523+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\
6524+ SQUASHFS_SWAP((s)->count, d, 0, 8);\
6525+ SQUASHFS_SWAP((s)->start_block, d, 8, 24);\
6526+}
6527+
6528+#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\
6529+ SQUASHFS_SWAP_START\
6530+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\
6531+ SQUASHFS_SWAP((s)->offset, d, 0, 13);\
6532+ SQUASHFS_SWAP((s)->type, d, 13, 3);\
6533+ SQUASHFS_SWAP((s)->size, d, 16, 8);\
6534+}
6535+
6536+#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\
6537+ SQUASHFS_SWAP_START\
6538+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\
6539+ SQUASHFS_SWAP((s)->start_block, d, 0, 32);\
6540+ SQUASHFS_SWAP((s)->size, d, 32, 32);\
6541+}
6542+
6543+#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n)
6544+
6545+/* fragment and fragment table defines */
6546+#define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2))
6547+
6548+#define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \
6549+ SQUASHFS_METADATA_SIZE)
6550+
6551+#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \
6552+ SQUASHFS_METADATA_SIZE)
6553+
6554+#define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \
6555+ SQUASHFS_METADATA_SIZE - 1) / \
6556+ SQUASHFS_METADATA_SIZE)
6557+
6558+#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\
6559+ sizeof(int))
6560+
6561+#endif
6562+
6563+#ifdef __KERNEL__
6564+
6565+/*
6566+ * macros used to swap each structure entry, taking into account
6567+ * bitfields and different bitfield placing conventions on differing
6568+ * architectures
6569+ */
6570+
6571+#include <asm/byteorder.h>
6572+
6573+#ifdef __BIG_ENDIAN
6574+ /* convert from little endian to big endian */
6575+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
6576+ tbits, b_pos)
6577+#else
6578+ /* convert from big endian to little endian */
6579+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
6580+ tbits, 64 - tbits - b_pos)
6581+#endif
6582+
6583+#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
6584+ b_pos = pos % 8;\
6585+ val = 0;\
6586+ s = (unsigned char *)p + (pos / 8);\
6587+ d = ((unsigned char *) &val) + 7;\
6588+ for(bits = 0; bits < (tbits + b_pos); bits += 8) \
6589+ *d-- = *s++;\
6590+ value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
6591+}
6592+
6593+#define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n);
6594+
6595+#endif
6596+#endif
6597diff -uNr a/include/linux/squashfs_fs_i.h b/include/linux/squashfs_fs_i.h
6598--- a/include/linux/squashfs_fs_i.h 1969-12-31 16:00:00.000000000 -0800
6599+++ b/include/linux/squashfs_fs_i.h 2008-08-13 16:16:05.000000000 -0700
6600@@ -0,0 +1,45 @@
6601+#ifndef SQUASHFS_FS_I
6602+#define SQUASHFS_FS_I
6603+/*
6604+ * Squashfs
6605+ *
6606+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
6607+ * Phillip Lougher <phillip@lougher.demon.co.uk>
6608+ *
6609+ * This program is free software; you can redistribute it and/or
6610+ * modify it under the terms of the GNU General Public License
6611+ * as published by the Free Software Foundation; either version 2,
6612+ * or (at your option) any later version.
6613+ *
6614+ * This program is distributed in the hope that it will be useful,
6615+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6616+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6617+ * GNU General Public License for more details.
6618+ *
6619+ * You should have received a copy of the GNU General Public License
6620+ * along with this program; if not, write to the Free Software
6621+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6622+ *
6623+ * squashfs_fs_i.h
6624+ */
6625+
6626+struct squashfs_inode_info {
6627+ long long start_block;
6628+ unsigned int offset;
6629+ union {
6630+ struct {
6631+ long long fragment_start_block;
6632+ unsigned int fragment_size;
6633+ unsigned int fragment_offset;
6634+ long long block_list_start;
6635+ } s1;
6636+ struct {
6637+ long long directory_index_start;
6638+ unsigned int directory_index_offset;
6639+ unsigned int directory_index_count;
6640+ unsigned int parent_inode;
6641+ } s2;
6642+ } u;
6643+ struct inode vfs_inode;
6644+};
6645+#endif
6646diff -uNr a/include/linux/squashfs_fs_sb.h b/include/linux/squashfs_fs_sb.h
6647--- a/include/linux/squashfs_fs_sb.h 1969-12-31 16:00:00.000000000 -0800
6648+++ b/include/linux/squashfs_fs_sb.h 2008-08-13 16:16:05.000000000 -0700
6649@@ -0,0 +1,78 @@
6650+#ifndef SQUASHFS_FS_SB
6651+#define SQUASHFS_FS_SB
6652+/*
6653+ * Squashfs
6654+ *
6655+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
6656+ * Phillip Lougher <phillip@lougher.demon.co.uk>
6657+ *
6658+ * This program is free software; you can redistribute it and/or
6659+ * modify it under the terms of the GNU General Public License
6660+ * as published by the Free Software Foundation; either version 2,
6661+ * or (at your option) any later version.
6662+ *
6663+ * This program is distributed in the hope that it will be useful,
6664+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6665+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6666+ * GNU General Public License for more details.
6667+ *
6668+ * You should have received a copy of the GNU General Public License
6669+ * along with this program; if not, write to the Free Software
6670+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6671+ *
6672+ * squashfs_fs_sb.h
6673+ */
6674+
6675+#include <linux/squashfs_fs.h>
6676+
6677+struct squashfs_cache_entry {
6678+ long long block;
6679+ int length;
6680+ int locked;
6681+ long long next_index;
6682+ char pending;
6683+ char error;
6684+ int waiting;
6685+ wait_queue_head_t wait_queue;
6686+ char *data;
6687+};
6688+
6689+struct squashfs_cache {
6690+ char *name;
6691+ int entries;
6692+ int block_size;
6693+ int next_blk;
6694+ int waiting;
6695+ int unused_blks;
6696+ int use_vmalloc;
6697+ spinlock_t lock;
6698+ wait_queue_head_t wait_queue;
6699+ struct squashfs_cache_entry entry[0];
6700+};
6701+
6702+struct squashfs_sb_info {
6703+ struct squashfs_super_block sblk;
6704+ int devblksize;
6705+ int devblksize_log2;
6706+ int swap;
6707+ struct squashfs_cache *block_cache;
6708+ struct squashfs_cache *fragment_cache;
6709+ int next_meta_index;
6710+ unsigned int *id_table;
6711+ long long *fragment_index;
6712+ unsigned int *fragment_index_2;
6713+ char *read_page;
6714+ struct mutex read_data_mutex;
6715+ struct mutex read_page_mutex;
6716+ struct mutex meta_index_mutex;
6717+ struct meta_index *meta_index;
6718+ z_stream stream;
6719+ long long *inode_lookup_table;
6720+ int (*read_inode)(struct inode *i, squashfs_inode_t \
6721+ inode);
6722+ long long (*read_blocklist)(struct inode *inode, int \
6723+ index, int readahead_blks, char *block_list, \
6724+ unsigned short **block_p, unsigned int *bsize);
6725+ int (*read_fragment_index_table)(struct super_block *s);
6726+};
6727+#endif
diff --git a/meta/packages/linux/linux-moblin2-2.6.27-rc1/0010_unionfs-2.4_for_2.6.27-rc1.patch b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0010_unionfs-2.4_for_2.6.27-rc1.patch
new file mode 100644
index 0000000000..8a2e83aa6c
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0010_unionfs-2.4_for_2.6.27-rc1.patch
@@ -0,0 +1,11320 @@
1diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
2index 52cd611..bc6b437 100644
3--- a/Documentation/filesystems/00-INDEX
4+++ b/Documentation/filesystems/00-INDEX
5@@ -106,6 +106,8 @@ udf.txt
6 - info and mount options for the UDF filesystem.
7 ufs.txt
8 - info on the ufs filesystem.
9+unionfs/
10+ - info on the unionfs filesystem
11 vfat.txt
12 - info on using the VFAT filesystem used in Windows NT and Windows 95
13 vfs.txt
14diff --git a/Documentation/filesystems/unionfs/00-INDEX b/Documentation/filesystems/unionfs/00-INDEX
15new file mode 100644
16index 0000000..96fdf67
17--- /dev/null
18+++ b/Documentation/filesystems/unionfs/00-INDEX
19@@ -0,0 +1,10 @@
20+00-INDEX
21+ - this file.
22+concepts.txt
23+ - A brief introduction of concepts.
24+issues.txt
25+ - A summary of known issues with unionfs.
26+rename.txt
27+ - Information regarding rename operations.
28+usage.txt
29+ - Usage information and examples.
30diff --git a/Documentation/filesystems/unionfs/concepts.txt b/Documentation/filesystems/unionfs/concepts.txt
31new file mode 100644
32index 0000000..b853788
33--- /dev/null
34+++ b/Documentation/filesystems/unionfs/concepts.txt
35@@ -0,0 +1,287 @@
36+Unionfs 2.x CONCEPTS:
37+=====================
38+
39+This file describes the concepts needed by a namespace unification file
40+system.
41+
42+
43+Branch Priority:
44+================
45+
46+Each branch is assigned a unique priority - starting from 0 (highest
47+priority). No two branches can have the same priority.
48+
49+
50+Branch Mode:
51+============
52+
53+Each branch is assigned a mode - read-write or read-only. This allows
54+directories on media mounted read-write to be used in a read-only manner.
55+
56+
57+Whiteouts:
58+==========
59+
60+A whiteout removes a file name from the namespace. Whiteouts are needed when
61+one attempts to remove a file on a read-only branch.
62+
63+Suppose we have a two-branch union, where branch 0 is read-write and branch
64+1 is read-only. And a file 'foo' on branch 1:
65+
66+./b0/
67+./b1/
68+./b1/foo
69+
70+The unified view would simply be:
71+
72+./union/
73+./union/foo
74+
75+Since 'foo' is stored on a read-only branch, it cannot be removed. A
76+whiteout is used to remove the name 'foo' from the unified namespace. Again,
77+since branch 1 is read-only, the whiteout cannot be created there. So, we
78+try on a higher priority (lower numerically) branch and create the whiteout
79+there.
80+
81+./b0/
82+./b0/.wh.foo
83+./b1/
84+./b1/foo
85+
86+Later, when Unionfs traverses branches (due to lookup or readdir), it
87+eliminate 'foo' from the namespace (as well as the whiteout itself.)
88+
89+
90+Opaque Directories:
91+===================
92+
93+Assume we have a unionfs mount comprising of two branches. Branch 0 is
94+empty; branch 1 has the directory /a and file /a/f. Let's say we mount a
95+union of branch 0 as read-write and branch 1 as read-only. Now, let's say
96+we try to perform the following operation in the union:
97+
98+ rm -fr a
99+
100+Because branch 1 is not writable, we cannot physically remove the file /a/f
101+or the directory /a. So instead, we will create a whiteout in branch 0
102+named /.wh.a, masking out the name "a" from branch 1. Next, let's say we
103+try to create a directory named "a" as follows:
104+
105+ mkdir a
106+
107+Because we have a whiteout for "a" already, Unionfs behaves as if "a"
108+doesn't exist, and thus will delete the whiteout and replace it with an
109+actual directory named "a".
110+
111+The problem now is that if you try to "ls" in the union, Unionfs will
112+perform is normal directory name unification, for *all* directories named
113+"a" in all branches. This will cause the file /a/f from branch 1 to
114+re-appear in the union's namespace, which violates Unix semantics.
115+
116+To avoid this problem, we have a different form of whiteouts for
117+directories, called "opaque directories" (same as BSD Union Mount does).
118+Whenever we replace a whiteout with a directory, that directory is marked as
119+opaque. In Unionfs 2.x, it means that we create a file named
120+/a/.wh.__dir_opaque in branch 0, after having created directory /a there.
121+When unionfs notices that a directory is opaque, it stops all namespace
122+operations (including merging readdir contents) at that opaque directory.
123+This prevents re-exposing names from masked out directories.
124+
125+
126+Duplicate Elimination:
127+======================
128+
129+It is possible for files on different branches to have the same name.
130+Unionfs then has to select which instance of the file to show to the user.
131+Given the fact that each branch has a priority associated with it, the
132+simplest solution is to take the instance from the highest priority
133+(numerically lowest value) and "hide" the others.
134+
135+
136+Unlinking:
137+=========
138+
139+Unlink operation on non-directory instances is optimized to remove the
140+maximum possible objects in case multiple underlying branches have the same
141+file name. The unlink operation will first try to delete file instances
142+from highest priority branch and then move further to delete from remaining
143+branches in order of their decreasing priority. Consider a case (F..D..F),
144+where F is a file and D is a directory of the same name; here, some
145+intermediate branch could have an empty directory instance with the same
146+name, so this operation also tries to delete this directory instance and
147+proceed further to delete from next possible lower priority branch. The
148+unionfs unlink operation will smoothly delete the files with same name from
149+all possible underlying branches. In case if some error occurs, it creates
150+whiteout in highest priority branch that will hide file instance in rest of
151+the branches. An error could occur either if an unlink operations in any of
152+the underlying branch failed or if a branch has no write permission.
153+
154+This unlinking policy is known as "delete all" and it has the benefit of
155+overall reducing the number of inodes used by duplicate files, and further
156+reducing the total number of inodes consumed by whiteouts. The cost is of
157+extra processing, but testing shows this extra processing is well worth the
158+savings.
159+
160+
161+Copyup:
162+=======
163+
164+When a change is made to the contents of a file's data or meta-data, they
165+have to be stored somewhere. The best way is to create a copy of the
166+original file on a branch that is writable, and then redirect the write
167+though to this copy. The copy must be made on a higher priority branch so
168+that lookup and readdir return this newer "version" of the file rather than
169+the original (see duplicate elimination).
170+
171+An entire unionfs mount can be read-only or read-write. If it's read-only,
172+then none of the branches will be written to, even if some of the branches
173+are physically writeable. If the unionfs mount is read-write, then the
174+leftmost (highest priority) branch must be writeable (for copyup to take
175+place); the remaining branches can be any mix of read-write and read-only.
176+
177+In a writeable mount, unionfs will create new files/dir in the leftmost
178+branch. If one tries to modify a file in a read-only branch/media, unionfs
179+will copyup the file to the leftmost branch and modify it there. If you try
180+to modify a file from a writeable branch which is not the leftmost branch,
181+then unionfs will modify it in that branch; this is useful if you, say,
182+unify differnet packages (e.g., apache, sendmail, ftpd, etc.) and you want
183+changes to specific package files to remain logically in the directory where
184+they came from.
185+
186+Cache Coherency:
187+================
188+
189+Unionfs users often want to be able to modify files and directories directly
190+on the lower branches, and have those changes be visible at the Unionfs
191+level. This means that data (e.g., pages) and meta-data (dentries, inodes,
192+open files, etc.) have to be synchronized between the upper and lower
193+layers. In other words, the newest changes from a layer below have to be
194+propagated to the Unionfs layer above. If the two layers are not in sync, a
195+cache incoherency ensues, which could lead to application failures and even
196+oopses. The Linux kernel, however, has a rather limited set of mechanisms
197+to ensure this inter-layer cache coherency---so Unionfs has to do most of
198+the hard work on its own.
199+
200+Maintaining Invariants:
201+
202+The way Unionfs ensures cache coherency is as follows. At each entry point
203+to a Unionfs file system method, we call a utility function to validate the
204+primary objects of this method. Generally, we call unionfs_file_revalidate
205+on open files, and __unionfs_d_revalidate_chain on dentries (which also
206+validates inodes). These utility functions check to see whether the upper
207+Unionfs object is in sync with any of the lower objects that it represents.
208+The checks we perform include whether the Unionfs superblock has a newer
209+generation number, or if any of the lower objects mtime's or ctime's are
210+newer. (Note: generation numbers change when branch-management commands are
211+issued, so in a way, maintaining cache coherency is also very important for
212+branch-management.) If indeed we determine that any Unionfs object is no
213+longer in sync with its lower counterparts, then we rebuild that object
214+similarly to how we do so for branch-management.
215+
216+While rebuilding Unionfs's objects, we also purge any page mappings and
217+truncate inode pages (see fs/unionfs/dentry.c:purge_inode_data). This is to
218+ensure that Unionfs will re-get the newer data from the lower branches. We
219+perform this purging only if the Unionfs operation in question is a reading
220+operation; if Unionfs is performing a data writing operation (e.g., ->write,
221+->commit_write, etc.) then we do NOT flush the lower mappings/pages: this is
222+because (1) a self-deadlock could occur and (2) the upper Unionfs pages are
223+considered more authoritative anyway, as they are newer and will overwrite
224+any lower pages.
225+
226+Unionfs maintains the following important invariant regarding mtime's,
227+ctime's, and atime's: the upper inode object's times are the max() of all of
228+the lower ones. For non-directory objects, there's only one object below,
229+so the mapping is simple; for directory objects, there could me multiple
230+lower objects and we have to sync up with the newest one of all the lower
231+ones. This invariant is important to maintain, especially for directories
232+(besides, we need this to be POSIX compliant). A union could comprise
233+multiple writable branches, each of which could change. If we don't reflect
234+the newest possible mtime/ctime, some applications could fail. For example,
235+NFSv2/v3 exports check for newer directory mtimes on the server to determine
236+if the client-side attribute cache should be purged.
237+
238+To maintain these important invariants, of course, Unionfs carefully
239+synchronizes upper and lower times in various places. For example, if we
240+copy-up a file to a top-level branch, the parent directory where the file
241+was copied up to will now have a new mtime: so after a successful copy-up,
242+we sync up with the new top-level branch's parent directory mtime.
243+
244+Implementation:
245+
246+This cache-coherency implementation is efficient because it defers any
247+synchronizing between the upper and lower layers until absolutely needed.
248+Consider the example a common situation where users perform a lot of lower
249+changes, such as untarring a whole package. While these take place,
250+typically the user doesn't access the files via Unionfs; only after the
251+lower changes are done, does the user try to access the lower files. With
252+our cache-coherency implementation, the entirety of the changes to the lower
253+branches will not result in a single CPU cycle spent at the Unionfs level
254+until the user invokes a system call that goes through Unionfs.
255+
256+We have considered two alternate cache-coherency designs. (1) Using the
257+dentry/inode notify functionality to register interest in finding out about
258+any lower changes. This is a somewhat limited and also a heavy-handed
259+approach which could result in many notifications to the Unionfs layer upon
260+each small change at the lower layer (imagine a file being modified multiple
261+times in rapid succession). (2) Rewriting the VFS to support explicit
262+callbacks from lower objects to upper objects. We began exploring such an
263+implementation, but found it to be very complicated--it would have resulted
264+in massive VFS/MM changes which are unlikely to be accepted by the LKML
265+community. We therefore believe that our current cache-coherency design and
266+implementation represent the best approach at this time.
267+
268+Limitations:
269+
270+Our implementation works in that as long as a user process will have caused
271+Unionfs to be called, directly or indirectly, even to just do
272+->d_revalidate; then we will have purged the current Unionfs data and the
273+process will see the new data. For example, a process that continually
274+re-reads the same file's data will see the NEW data as soon as the lower
275+file had changed, upon the next read(2) syscall (even if the file is still
276+open!) However, this doesn't work when the process re-reads the open file's
277+data via mmap(2) (unless the user unmaps/closes the file and remaps/reopens
278+it). Once we respond to ->readpage(s), then the kernel maps the page into
279+the process's address space and there doesn't appear to be a way to force
280+the kernel to invalidate those pages/mappings, and force the process to
281+re-issue ->readpage. If there's a way to invalidate active mappings and
282+force a ->readpage, let us know please (invalidate_inode_pages2 doesn't do
283+the trick).
284+
285+Our current Unionfs code has to perform many file-revalidation calls. It
286+would be really nice if the VFS would export an optional file system hook
287+->file_revalidate (similarly to dentry->d_revalidate) that will be called
288+before each VFS op that has a "struct file" in it.
289+
290+Certain file systems have micro-second granularity (or better) for inode
291+times, and asynchronous actions could cause those times to change with some
292+small delay. In such cases, Unionfs may see a changed inode time that only
293+differs by a tiny fraction of a second: such a change may be a false
294+positive indication that the lower object has changed, whereas if unionfs
295+waits a little longer, that false indication will not be seen. (These false
296+positives are harmless, because they would at most cause unionfs to
297+re-validate an object that may need no revalidation, and print a debugging
298+message that clutters the console/logs.) Therefore, to minimize the chances
299+of these situations, we delay the detection of changed times by a small
300+factor of a few seconds, called UNIONFS_MIN_CC_TIME (which defaults to 3
301+seconds, as does NFS). This means that we will detect the change, only a
302+couple of seconds later, if indeed the time change persists in the lower
303+file object. This delayed detection has an added performance benefit: we
304+reduce the number of times that unionfs has to revalidate objects, in case
305+there's a lot of concurrent activity on both the upper and lower objects,
306+for the same file(s). Lastly, this delayed time attribute detection is
307+similar to how NFS clients operate (e.g., acregmin).
308+
309+Finally, there is no way currently in Linux to prevent lower directories
310+from being moved around (i.e., topology changes); there's no way to prevent
311+modifications to directory sub-trees of whole file systems which are mounted
312+read-write. It is therefore possible for in-flight operations in unionfs to
313+take place, while a lower directory is being moved around. Therefore, if
314+you try to, say, create a new file in a directory through unionfs, while the
315+directory is being moved around directly, then the new file may get created
316+in the new location where that directory was moved to. This is a somewhat
317+similar behaviour in NFS: an NFS client could be creating a new file while
318+th NFS server is moving th directory around; the file will get successfully
319+created in the new location. (The one exception in unionfs is that if the
320+branch is marked read-only by unionfs, then a copyup will take place.)
321+
322+For more information, see <http://unionfs.filesystems.org/>.
323diff --git a/Documentation/filesystems/unionfs/issues.txt b/Documentation/filesystems/unionfs/issues.txt
324new file mode 100644
325index 0000000..f4b7e7e
326--- /dev/null
327+++ b/Documentation/filesystems/unionfs/issues.txt
328@@ -0,0 +1,28 @@
329+KNOWN Unionfs 2.x ISSUES:
330+=========================
331+
332+1. Unionfs should not use lookup_one_len() on the underlying f/s as it
333+ confuses NFSv4. Currently, unionfs_lookup() passes lookup intents to the
334+ lower file-system, this eliminates part of the problem. The remaining
335+ calls to lookup_one_len may need to be changed to pass an intent. We are
336+ currently introducing VFS changes to fs/namei.c's do_path_lookup() to
337+ allow proper file lookup and opening in stackable file systems.
338+
339+2. Lockdep (a debugging feature) isn't aware of stacking, and so it
340+ incorrectly complains about locking problems. The problem boils down to
341+ this: Lockdep considers all objects of a certain type to be in the same
342+ class, for example, all inodes. Lockdep doesn't like to see a lock held
343+ on two inodes within the same task, and warns that it could lead to a
344+ deadlock. However, stackable file systems do precisely that: they lock
345+ an upper object, and then a lower object, in a strict order to avoid
346+ locking problems; in addition, Unionfs, as a fan-out file system, may
347+ have to lock several lower inodes. We are currently looking into Lockdep
348+ to see how to make it aware of stackable file systems. For now, we
349+ temporarily disable lockdep when calling vfs methods on lower objects,
350+ but only for those places where lockdep complained. While this solution
351+ may seem unclean, it is not without precedent: other places in the kernel
352+ also do similar temporary disabling, of course after carefully having
353+ checked that it is the right thing to do. Anyway, you get any warnings
354+ from Lockdep, please report them to the Unionfs maintainers.
355+
356+For more information, see <http://unionfs.filesystems.org/>.
357diff --git a/Documentation/filesystems/unionfs/rename.txt b/Documentation/filesystems/unionfs/rename.txt
358new file mode 100644
359index 0000000..e20bb82
360--- /dev/null
361+++ b/Documentation/filesystems/unionfs/rename.txt
362@@ -0,0 +1,31 @@
363+Rename is a complex beast. The following table shows which rename(2) operations
364+should succeed and which should fail.
365+
366+o: success
367+E: error (either unionfs or vfs)
368+X: EXDEV
369+
370+none = file does not exist
371+file = file is a file
372+dir = file is a empty directory
373+child= file is a non-empty directory
374+wh = file is a directory containing only whiteouts; this makes it logically
375+ empty
376+
377+ none file dir child wh
378+file o o E E E
379+dir o E o E o
380+child X E X E X
381+wh o E o E o
382+
383+
384+Renaming directories:
385+=====================
386+
387+Whenever a empty (either physically or logically) directory is being renamed,
388+the following sequence of events should take place:
389+
390+1) Remove whiteouts from both source and destination directory
391+2) Rename source to destination
392+3) Make destination opaque to prevent anything under it from showing up
393+
394diff --git a/Documentation/filesystems/unionfs/usage.txt b/Documentation/filesystems/unionfs/usage.txt
395new file mode 100644
396index 0000000..1adde69
397--- /dev/null
398+++ b/Documentation/filesystems/unionfs/usage.txt
399@@ -0,0 +1,134 @@
400+Unionfs is a stackable unification file system, which can appear to merge
401+the contents of several directories (branches), while keeping their physical
402+content separate. Unionfs is useful for unified source tree management,
403+merged contents of split CD-ROM, merged separate software package
404+directories, data grids, and more. Unionfs allows any mix of read-only and
405+read-write branches, as well as insertion and deletion of branches anywhere
406+in the fan-out. To maintain Unix semantics, Unionfs handles elimination of
407+duplicates, partial-error conditions, and more.
408+
409+GENERAL SYNTAX
410+==============
411+
412+# mount -t unionfs -o <OPTIONS>,<BRANCH-OPTIONS> none MOUNTPOINT
413+
414+OPTIONS can be any legal combination of:
415+
416+- ro # mount file system read-only
417+- rw # mount file system read-write
418+- remount # remount the file system (see Branch Management below)
419+- incgen # increment generation no. (see Cache Consistency below)
420+
421+BRANCH-OPTIONS can be either (1) a list of branches given to the "dirs="
422+option, or (2) a list of individual branch manipulation commands, combined
423+with the "remount" option, and is further described in the "Branch
424+Management" section below.
425+
426+The syntax for the "dirs=" mount option is:
427+
428+ dirs=branch[=ro|=rw][:...]
429+
430+The "dirs=" option takes a colon-delimited list of directories to compose
431+the union, with an optional branch mode for each of those directories.
432+Directories that come earlier (specified first, on the left) in the list
433+have a higher precedence than those which come later. Additionally,
434+read-only or read-write permissions of the branch can be specified by
435+appending =ro or =rw (default) to each directory. See the Copyup section in
436+concepts.txt, for a description of Unionfs's behavior when mixing read-only
437+and read-write branches and mounts.
438+
439+Syntax:
440+
441+ dirs=/branch1[=ro|=rw]:/branch2[=ro|=rw]:...:/branchN[=ro|=rw]
442+
443+Example:
444+
445+ dirs=/writable_branch=rw:/read-only_branch=ro
446+
447+
448+BRANCH MANAGEMENT
449+=================
450+
451+Once you mount your union for the first time, using the "dirs=" option, you
452+can then change the union's overall mode or reconfigure the branches, using
453+the remount option, as follows.
454+
455+To downgrade a union from read-write to read-only:
456+
457+# mount -t unionfs -o remount,ro none MOUNTPOINT
458+
459+To upgrade a union from read-only to read-write:
460+
461+# mount -t unionfs -o remount,rw none MOUNTPOINT
462+
463+To delete a branch /foo, regardless where it is in the current union:
464+
465+# mount -t unionfs -o remount,del=/foo none MOUNTPOINT
466+
467+To insert (add) a branch /foo before /bar:
468+
469+# mount -t unionfs -o remount,add=/bar:/foo none MOUNTPOINT
470+
471+To insert (add) a branch /foo (with the "rw" mode flag) before /bar:
472+
473+# mount -t unionfs -o remount,add=/bar:/foo=rw none MOUNTPOINT
474+
475+To insert (add) a branch /foo (in "rw" mode) at the very beginning (i.e., a
476+new highest-priority branch), you can use the above syntax, or use a short
477+hand version as follows:
478+
479+# mount -t unionfs -o remount,add=/foo none MOUNTPOINT
480+
481+To append a branch to the very end (new lowest-priority branch):
482+
483+# mount -t unionfs -o remount,add=:/foo none MOUNTPOINT
484+
485+To append a branch to the very end (new lowest-priority branch), in
486+read-only mode:
487+
488+# mount -t unionfs -o remount,add=:/foo=ro none MOUNTPOINT
489+
490+Finally, to change the mode of one existing branch, say /foo, from read-only
491+to read-write, and change /bar from read-write to read-only:
492+
493+# mount -t unionfs -o remount,mode=/foo=rw,mode=/bar=ro none MOUNTPOINT
494+
495+Note: in Unionfs 2.x, you cannot set the leftmost branch to readonly because
496+then Unionfs won't have any writable place for copyups to take place.
497+Moreover, the VFS can get confused when it tries to modify something in a
498+file system mounted read-write, but isn't permitted to write to it.
499+Instead, you should set the whole union as readonly, as described above.
500+If, however, you must set the leftmost branch as readonly, perhaps so you
501+can get a snapshot of it at a point in time, then you should insert a new
502+writable top-level branch, and mark the one you want as readonly. This can
503+be accomplished as follows, assuming that /foo is your current leftmost
504+branch:
505+
506+# mount -t tmpfs -o size=NNN /new
507+# mount -t unionfs -o remount,add=/new,mode=/foo=ro none MOUNTPOINT
508+<do what you want safely in /foo>
509+# mount -t unionfs -o remount,del=/new,mode=/foo=rw none MOUNTPOINT
510+<check if there's anything in /new you want to preserve>
511+# umount /new
512+
513+CACHE CONSISTENCY
514+=================
515+
516+If you modify any file on any of the lower branches directly, while there is
517+a Unionfs 2.x mounted above any of those branches, you should tell Unionfs
518+to purge its caches and re-get the objects. To do that, you have to
519+increment the generation number of the superblock using the following
520+command:
521+
522+# mount -t unionfs -o remount,incgen none MOUNTPOINT
523+
524+Note that the older way of incrementing the generation number using an
525+ioctl, is no longer supported in Unionfs 2.0 and newer. Ioctls in general
526+are not encouraged. Plus, an ioctl is per-file concept, whereas the
527+generation number is a per-file-system concept. Worse, such an ioctl
528+requires an open file, which then has to be invalidated by the very nature
529+of the generation number increase (read: the old generation increase ioctl
530+was pretty racy).
531+
532+
533+For more information, see <http://unionfs.filesystems.org/>.
534diff --git a/MAINTAINERS b/MAINTAINERS
535index deedc0d..c722f8e 100644
536--- a/MAINTAINERS
537+++ b/MAINTAINERS
538@@ -4173,6 +4173,14 @@ L: linux-kernel@vger.kernel.org
539 W: http://www.kernel.dk
540 S: Maintained
541
542+UNIONFS
543+P: Erez Zadok
544+M: ezk@cs.sunysb.edu
545+L: unionfs@filesystems.org
546+W: http://unionfs.filesystems.org
547+T: git git.kernel.org/pub/scm/linux/kernel/git/ezk/unionfs.git
548+S: Maintained
549+
550 USB ACM DRIVER
551 P: Oliver Neukum
552 M: oliver@neukum.name
553diff --git a/fs/Kconfig b/fs/Kconfig
554index d387358..31610a2 100644
555--- a/fs/Kconfig
556+++ b/fs/Kconfig
557@@ -981,6 +981,47 @@ config CONFIGFS_FS
558
559 endmenu
560
561+menu "Layered filesystems"
562+
563+config ECRYPT_FS
564+ tristate "eCrypt filesystem layer support (EXPERIMENTAL)"
565+ depends on EXPERIMENTAL && KEYS && CRYPTO && NET
566+ help
567+ Encrypted filesystem that operates on the VFS layer. See
568+ <file:Documentation/filesystems/ecryptfs.txt> to learn more about
569+ eCryptfs. Userspace components are required and can be
570+ obtained from <http://ecryptfs.sf.net>.
571+
572+ To compile this file system support as a module, choose M here: the
573+ module will be called ecryptfs.
574+
575+config UNION_FS
576+ tristate "Union file system (EXPERIMENTAL)"
577+ depends on EXPERIMENTAL
578+ help
579+ Unionfs is a stackable unification file system, which appears to
580+ merge the contents of several directories (branches), while keeping
581+ their physical content separate.
582+
583+ See <http://unionfs.filesystems.org> for details
584+
585+config UNION_FS_XATTR
586+ bool "Unionfs extended attributes"
587+ depends on UNION_FS
588+ help
589+ Extended attributes are name:value pairs associated with inodes by
590+ the kernel or by users (see the attr(5) manual page).
591+
592+ If unsure, say N.
593+
594+config UNION_FS_DEBUG
595+ bool "Debug Unionfs"
596+ depends on UNION_FS
597+ help
598+ If you say Y here, you can turn on debugging output from Unionfs.
599+
600+endmenu
601+
602 menu "Miscellaneous filesystems"
603
604 config ADFS_FS
605@@ -1033,18 +1074,6 @@ config AFFS_FS
606 To compile this file system support as a module, choose M here: the
607 module will be called affs. If unsure, say N.
608
609-config ECRYPT_FS
610- tristate "eCrypt filesystem layer support (EXPERIMENTAL)"
611- depends on EXPERIMENTAL && KEYS && CRYPTO && NET
612- help
613- Encrypted filesystem that operates on the VFS layer. See
614- <file:Documentation/filesystems/ecryptfs.txt> to learn more about
615- eCryptfs. Userspace components are required and can be
616- obtained from <http://ecryptfs.sf.net>.
617-
618- To compile this file system support as a module, choose M here: the
619- module will be called ecryptfs.
620-
621 config HFS_FS
622 tristate "Apple Macintosh file system support (EXPERIMENTAL)"
623 depends on BLOCK && EXPERIMENTAL
624diff --git a/fs/Makefile b/fs/Makefile
625index a1482a5..9bf3915 100644
626--- a/fs/Makefile
627+++ b/fs/Makefile
628@@ -86,6 +86,7 @@ obj-$(CONFIG_ISO9660_FS) += isofs/
629 obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+
630 obj-$(CONFIG_HFS_FS) += hfs/
631 obj-$(CONFIG_ECRYPT_FS) += ecryptfs/
632+obj-$(CONFIG_UNION_FS) += unionfs/
633 obj-$(CONFIG_VXFS_FS) += freevxfs/
634 obj-$(CONFIG_NFS_FS) += nfs/
635 obj-$(CONFIG_EXPORTFS) += exportfs/
636diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c
637index 5e59658..4621f89 100644
638--- a/fs/ecryptfs/dentry.c
639+++ b/fs/ecryptfs/dentry.c
640@@ -62,7 +62,7 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
641 struct inode *lower_inode =
642 ecryptfs_inode_to_lower(dentry->d_inode);
643
644- fsstack_copy_attr_all(dentry->d_inode, lower_inode, NULL);
645+ fsstack_copy_attr_all(dentry->d_inode, lower_inode);
646 }
647 out:
648 return rc;
649diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
650index 89209f0..d99a83e 100644
651--- a/fs/ecryptfs/inode.c
652+++ b/fs/ecryptfs/inode.c
653@@ -589,9 +589,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
654 lower_new_dir_dentry->d_inode, lower_new_dentry);
655 if (rc)
656 goto out_lock;
657- fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL);
658+ fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode);
659 if (new_dir != old_dir)
660- fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode, NULL);
661+ fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode);
662 out_lock:
663 unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
664 dput(lower_new_dentry->d_parent);
665@@ -913,7 +913,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
666 rc = notify_change(lower_dentry, ia);
667 mutex_unlock(&lower_dentry->d_inode->i_mutex);
668 out:
669- fsstack_copy_attr_all(inode, lower_inode, NULL);
670+ fsstack_copy_attr_all(inode, lower_inode);
671 return rc;
672 }
673
674diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
675index 448dfd5..db2db5d 100644
676--- a/fs/ecryptfs/main.c
677+++ b/fs/ecryptfs/main.c
678@@ -197,7 +197,7 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry,
679 d_add(dentry, inode);
680 else
681 d_instantiate(dentry, inode);
682- fsstack_copy_attr_all(inode, lower_inode, NULL);
683+ fsstack_copy_attr_all(inode, lower_inode);
684 /* This size will be overwritten for real files w/ headers and
685 * other metadata */
686 fsstack_copy_inode_size(inode, lower_inode);
687diff --git a/fs/namei.c b/fs/namei.c
688index a7b0a0b..d05ee31 100644
689--- a/fs/namei.c
690+++ b/fs/namei.c
691@@ -392,6 +392,7 @@ void release_open_intent(struct nameidata *nd)
692 else
693 fput(nd->intent.open.file);
694 }
695+EXPORT_SYMBOL_GPL(release_open_intent);
696
697 static inline struct dentry *
698 do_revalidate(struct dentry *dentry, struct nameidata *nd)
699diff --git a/fs/splice.c b/fs/splice.c
700index b30311b..204bb3c 100644
701--- a/fs/splice.c
702+++ b/fs/splice.c
703@@ -887,8 +887,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
704 /*
705 * Attempt to initiate a splice from pipe to file.
706 */
707-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
708- loff_t *ppos, size_t len, unsigned int flags)
709+long vfs_splice_from(struct pipe_inode_info *pipe, struct file *out,
710+ loff_t *ppos, size_t len, unsigned int flags)
711 {
712 int ret;
713
714@@ -904,13 +904,14 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
715
716 return out->f_op->splice_write(pipe, out, ppos, len, flags);
717 }
718+EXPORT_SYMBOL_GPL(vfs_splice_from);
719
720 /*
721 * Attempt to initiate a splice from a file to a pipe.
722 */
723-static long do_splice_to(struct file *in, loff_t *ppos,
724- struct pipe_inode_info *pipe, size_t len,
725- unsigned int flags)
726+long vfs_splice_to(struct file *in, loff_t *ppos,
727+ struct pipe_inode_info *pipe, size_t len,
728+ unsigned int flags)
729 {
730 int ret;
731
732@@ -926,6 +927,7 @@ static long do_splice_to(struct file *in, loff_t *ppos,
733
734 return in->f_op->splice_read(in, ppos, pipe, len, flags);
735 }
736+EXPORT_SYMBOL_GPL(vfs_splice_to);
737
738 /**
739 * splice_direct_to_actor - splices data directly between two non-pipes
740@@ -995,7 +997,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
741 size_t read_len;
742 loff_t pos = sd->pos, prev_pos = pos;
743
744- ret = do_splice_to(in, &pos, pipe, len, flags);
745+ ret = vfs_splice_to(in, &pos, pipe, len, flags);
746 if (unlikely(ret <= 0))
747 goto out_release;
748
749@@ -1054,7 +1056,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe,
750 {
751 struct file *file = sd->u.file;
752
753- return do_splice_from(pipe, file, &sd->pos, sd->total_len, sd->flags);
754+ return vfs_splice_from(pipe, file, &sd->pos, sd->total_len, sd->flags);
755 }
756
757 /**
758@@ -1128,7 +1130,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
759 } else
760 off = &out->f_pos;
761
762- ret = do_splice_from(pipe, out, off, len, flags);
763+ ret = vfs_splice_from(pipe, out, off, len, flags);
764
765 if (off_out && copy_to_user(off_out, off, sizeof(loff_t)))
766 ret = -EFAULT;
767@@ -1149,7 +1151,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
768 } else
769 off = &in->f_pos;
770
771- ret = do_splice_to(in, off, pipe, len, flags);
772+ ret = vfs_splice_to(in, off, pipe, len, flags);
773
774 if (off_in && copy_to_user(off_in, off, sizeof(loff_t)))
775 ret = -EFAULT;
776diff --git a/fs/stack.c b/fs/stack.c
777index 67716f6..a66ff6c 100644
778--- a/fs/stack.c
779+++ b/fs/stack.c
780@@ -1,24 +1,82 @@
781+/*
782+ * Copyright (c) 2006-2007 Erez Zadok
783+ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
784+ * Copyright (c) 2006-2007 Stony Brook University
785+ * Copyright (c) 2006-2007 The Research Foundation of SUNY
786+ *
787+ * This program is free software; you can redistribute it and/or modify
788+ * it under the terms of the GNU General Public License version 2 as
789+ * published by the Free Software Foundation.
790+ */
791+
792 #include <linux/module.h>
793 #include <linux/fs.h>
794 #include <linux/fs_stack.h>
795
796-/* does _NOT_ require i_mutex to be held.
797+/*
798+ * does _NOT_ require i_mutex to be held.
799 *
800 * This function cannot be inlined since i_size_{read,write} is rather
801 * heavy-weight on 32-bit systems
802 */
803-void fsstack_copy_inode_size(struct inode *dst, const struct inode *src)
804+void fsstack_copy_inode_size(struct inode *dst, struct inode *src)
805 {
806- i_size_write(dst, i_size_read((struct inode *)src));
807- dst->i_blocks = src->i_blocks;
808+ loff_t i_size;
809+ blkcnt_t i_blocks;
810+
811+ /*
812+ * i_size_read() includes its own seqlocking and protection from
813+ * preemption (see include/linux/fs.h): we need nothing extra for
814+ * that here, and prefer to avoid nesting locks than attempt to
815+ * keep i_size and i_blocks in synch together.
816+ */
817+ i_size = i_size_read(src);
818+
819+ /*
820+ * But if CONFIG_LSF (on 32-bit), we ought to make an effort to keep
821+ * the two halves of i_blocks in synch despite SMP or PREEMPT - though
822+ * stat's generic_fillattr() doesn't bother, and we won't be applying
823+ * quotas (where i_blocks does become important) at the upper level.
824+ *
825+ * We don't actually know what locking is used at the lower level; but
826+ * if it's a filesystem that supports quotas, it will be using i_lock
827+ * as in inode_add_bytes(). tmpfs uses other locking, and its 32-bit
828+ * is (just) able to exceed 2TB i_size with the aid of holes; but its
829+ * i_blocks cannot carry into the upper long without almost 2TB swap -
830+ * let's ignore that case.
831+ */
832+ if (sizeof(i_blocks) > sizeof(long))
833+ spin_lock(&src->i_lock);
834+ i_blocks = src->i_blocks;
835+ if (sizeof(i_blocks) > sizeof(long))
836+ spin_unlock(&src->i_lock);
837+
838+ /*
839+ * If CONFIG_SMP on 32-bit, it's vital for fsstack_copy_inode_size()
840+ * to hold some lock around i_size_write(), otherwise i_size_read()
841+ * may spin forever (see include/linux/fs.h). We don't necessarily
842+ * hold i_mutex when this is called, so take i_lock for that case.
843+ *
844+ * And if CONFIG_LSF (on 32-bit), continue our effort to keep the
845+ * two halves of i_blocks in synch despite SMP or PREEMPT: use i_lock
846+ * for that case too, and do both at once by combining the tests.
847+ *
848+ * There is none of this locking overhead in the 64-bit case.
849+ */
850+ if (sizeof(i_size) > sizeof(long) || sizeof(i_blocks) > sizeof(long))
851+ spin_lock(&dst->i_lock);
852+ i_size_write(dst, i_size);
853+ dst->i_blocks = i_blocks;
854+ if (sizeof(i_size) > sizeof(long) || sizeof(i_blocks) > sizeof(long))
855+ spin_unlock(&dst->i_lock);
856 }
857 EXPORT_SYMBOL_GPL(fsstack_copy_inode_size);
858
859-/* copy all attributes; get_nlinks is optional way to override the i_nlink
860+/*
861+ * copy all attributes; get_nlinks is optional way to override the i_nlink
862 * copying
863 */
864-void fsstack_copy_attr_all(struct inode *dest, const struct inode *src,
865- int (*get_nlinks)(struct inode *))
866+void fsstack_copy_attr_all(struct inode *dest, const struct inode *src)
867 {
868 dest->i_mode = src->i_mode;
869 dest->i_uid = src->i_uid;
870@@ -29,14 +87,6 @@ void fsstack_copy_attr_all(struct inode *dest, const struct inode *src,
871 dest->i_ctime = src->i_ctime;
872 dest->i_blkbits = src->i_blkbits;
873 dest->i_flags = src->i_flags;
874-
875- /*
876- * Update the nlinks AFTER updating the above fields, because the
877- * get_links callback may depend on them.
878- */
879- if (!get_nlinks)
880- dest->i_nlink = src->i_nlink;
881- else
882- dest->i_nlink = (*get_nlinks)(dest);
883+ dest->i_nlink = src->i_nlink;
884 }
885 EXPORT_SYMBOL_GPL(fsstack_copy_attr_all);
886diff --git a/fs/unionfs/Makefile b/fs/unionfs/Makefile
887new file mode 100644
888index 0000000..fa04e30
889--- /dev/null
890+++ b/fs/unionfs/Makefile
891@@ -0,0 +1,17 @@
892+UNIONFS_VERSION="2.4 (for 2.6.27-rc1)"
893+
894+EXTRA_CFLAGS += -DUNIONFS_VERSION=\"$(UNIONFS_VERSION)\"
895+
896+obj-$(CONFIG_UNION_FS) += unionfs.o
897+
898+unionfs-y := subr.o dentry.o file.o inode.o main.o super.o \
899+ rdstate.o copyup.o dirhelper.o rename.o unlink.o \
900+ lookup.o commonfops.o dirfops.o sioq.o mmap.o whiteout.o
901+
902+unionfs-$(CONFIG_UNION_FS_XATTR) += xattr.o
903+
904+unionfs-$(CONFIG_UNION_FS_DEBUG) += debug.o
905+
906+ifeq ($(CONFIG_UNION_FS_DEBUG),y)
907+EXTRA_CFLAGS += -DDEBUG
908+endif
909diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
910new file mode 100644
911index 0000000..5861970
912--- /dev/null
913+++ b/fs/unionfs/commonfops.c
914@@ -0,0 +1,905 @@
915+/*
916+ * Copyright (c) 2003-2008 Erez Zadok
917+ * Copyright (c) 2003-2006 Charles P. Wright
918+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
919+ * Copyright (c) 2005-2006 Junjiro Okajima
920+ * Copyright (c) 2005 Arun M. Krishnakumar
921+ * Copyright (c) 2004-2006 David P. Quigley
922+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
923+ * Copyright (c) 2003 Puja Gupta
924+ * Copyright (c) 2003 Harikesavan Krishnan
925+ * Copyright (c) 2003-2008 Stony Brook University
926+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
927+ *
928+ * This program is free software; you can redistribute it and/or modify
929+ * it under the terms of the GNU General Public License version 2 as
930+ * published by the Free Software Foundation.
931+ */
932+
933+#include "union.h"
934+
935+/*
936+ * 1) Copyup the file
937+ * 2) Rename the file to '.unionfs<original inode#><counter>' - obviously
938+ * stolen from NFS's silly rename
939+ */
940+static int copyup_deleted_file(struct file *file, struct dentry *dentry,
941+ int bstart, int bindex)
942+{
943+ static unsigned int counter;
944+ const int i_inosize = sizeof(dentry->d_inode->i_ino) * 2;
945+ const int countersize = sizeof(counter) * 2;
946+ const int nlen = sizeof(".unionfs") + i_inosize + countersize - 1;
947+ char name[nlen + 1];
948+ int err;
949+ struct dentry *tmp_dentry = NULL;
950+ struct dentry *lower_dentry;
951+ struct dentry *lower_dir_dentry = NULL;
952+
953+ lower_dentry = unionfs_lower_dentry_idx(dentry, bstart);
954+
955+ sprintf(name, ".unionfs%*.*lx",
956+ i_inosize, i_inosize, lower_dentry->d_inode->i_ino);
957+
958+ /*
959+ * Loop, looking for an unused temp name to copyup to.
960+ *
961+ * It's somewhat silly that we look for a free temp tmp name in the
962+ * source branch (bstart) instead of the dest branch (bindex), where
963+ * the final name will be created. We _will_ catch it if somehow
964+ * the name exists in the dest branch, but it'd be nice to catch it
965+ * sooner than later.
966+ */
967+retry:
968+ tmp_dentry = NULL;
969+ do {
970+ char *suffix = name + nlen - countersize;
971+
972+ dput(tmp_dentry);
973+ counter++;
974+ sprintf(suffix, "%*.*x", countersize, countersize, counter);
975+
976+ pr_debug("unionfs: trying to rename %s to %s\n",
977+ dentry->d_name.name, name);
978+
979+ tmp_dentry = lookup_one_len(name, lower_dentry->d_parent,
980+ nlen);
981+ if (IS_ERR(tmp_dentry)) {
982+ err = PTR_ERR(tmp_dentry);
983+ goto out;
984+ }
985+ } while (tmp_dentry->d_inode != NULL); /* need negative dentry */
986+ dput(tmp_dentry);
987+
988+ err = copyup_named_file(dentry->d_parent->d_inode, file, name, bstart,
989+ bindex,
990+ i_size_read(file->f_path.dentry->d_inode));
991+ if (err) {
992+ if (unlikely(err == -EEXIST))
993+ goto retry;
994+ goto out;
995+ }
996+
997+ /* bring it to the same state as an unlinked file */
998+ lower_dentry = unionfs_lower_dentry_idx(dentry, dbstart(dentry));
999+ if (!unionfs_lower_inode_idx(dentry->d_inode, bindex)) {
1000+ atomic_inc(&lower_dentry->d_inode->i_count);
1001+ unionfs_set_lower_inode_idx(dentry->d_inode, bindex,
1002+ lower_dentry->d_inode);
1003+ }
1004+ lower_dir_dentry = lock_parent(lower_dentry);
1005+ err = vfs_unlink(lower_dir_dentry->d_inode, lower_dentry);
1006+ unlock_dir(lower_dir_dentry);
1007+
1008+out:
1009+ if (!err)
1010+ unionfs_check_dentry(dentry);
1011+ return err;
1012+}
1013+
1014+/*
1015+ * put all references held by upper struct file and free lower file pointer
1016+ * array
1017+ */
1018+static void cleanup_file(struct file *file)
1019+{
1020+ int bindex, bstart, bend;
1021+ struct file **lower_files;
1022+ struct file *lower_file;
1023+ struct super_block *sb = file->f_path.dentry->d_sb;
1024+
1025+ lower_files = UNIONFS_F(file)->lower_files;
1026+ bstart = fbstart(file);
1027+ bend = fbend(file);
1028+
1029+ for (bindex = bstart; bindex <= bend; bindex++) {
1030+ int i; /* holds (possibly) updated branch index */
1031+ int old_bid;
1032+
1033+ lower_file = unionfs_lower_file_idx(file, bindex);
1034+ if (!lower_file)
1035+ continue;
1036+
1037+ /*
1038+ * Find new index of matching branch with an open
1039+ * file, since branches could have been added or
1040+ * deleted causing the one with open files to shift.
1041+ */
1042+ old_bid = UNIONFS_F(file)->saved_branch_ids[bindex];
1043+ i = branch_id_to_idx(sb, old_bid);
1044+ if (unlikely(i < 0)) {
1045+ printk(KERN_ERR "unionfs: no superblock for "
1046+ "file %p\n", file);
1047+ continue;
1048+ }
1049+
1050+ /* decrement count of open files */
1051+ branchput(sb, i);
1052+ /*
1053+ * fput will perform an mntput for us on the correct branch.
1054+ * Although we're using the file's old branch configuration,
1055+ * bindex, which is the old index, correctly points to the
1056+ * right branch in the file's branch list. In other words,
1057+ * we're going to mntput the correct branch even if branches
1058+ * have been added/removed.
1059+ */
1060+ fput(lower_file);
1061+ UNIONFS_F(file)->lower_files[bindex] = NULL;
1062+ UNIONFS_F(file)->saved_branch_ids[bindex] = -1;
1063+ }
1064+
1065+ UNIONFS_F(file)->lower_files = NULL;
1066+ kfree(lower_files);
1067+ kfree(UNIONFS_F(file)->saved_branch_ids);
1068+ /* set to NULL because caller needs to know if to kfree on error */
1069+ UNIONFS_F(file)->saved_branch_ids = NULL;
1070+}
1071+
1072+/* open all lower files for a given file */
1073+static int open_all_files(struct file *file)
1074+{
1075+ int bindex, bstart, bend, err = 0;
1076+ struct file *lower_file;
1077+ struct dentry *lower_dentry;
1078+ struct dentry *dentry = file->f_path.dentry;
1079+ struct super_block *sb = dentry->d_sb;
1080+
1081+ bstart = dbstart(dentry);
1082+ bend = dbend(dentry);
1083+
1084+ for (bindex = bstart; bindex <= bend; bindex++) {
1085+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
1086+ if (!lower_dentry)
1087+ continue;
1088+
1089+ dget(lower_dentry);
1090+ unionfs_mntget(dentry, bindex);
1091+ branchget(sb, bindex);
1092+
1093+ lower_file =
1094+ dentry_open(lower_dentry,
1095+ unionfs_lower_mnt_idx(dentry, bindex),
1096+ file->f_flags);
1097+ if (IS_ERR(lower_file)) {
1098+ err = PTR_ERR(lower_file);
1099+ goto out;
1100+ } else {
1101+ unionfs_set_lower_file_idx(file, bindex, lower_file);
1102+ }
1103+ }
1104+out:
1105+ return err;
1106+}
1107+
1108+/* open the highest priority file for a given upper file */
1109+static int open_highest_file(struct file *file, bool willwrite)
1110+{
1111+ int bindex, bstart, bend, err = 0;
1112+ struct file *lower_file;
1113+ struct dentry *lower_dentry;
1114+ struct dentry *dentry = file->f_path.dentry;
1115+ struct inode *parent_inode = dentry->d_parent->d_inode;
1116+ struct super_block *sb = dentry->d_sb;
1117+
1118+ bstart = dbstart(dentry);
1119+ bend = dbend(dentry);
1120+
1121+ lower_dentry = unionfs_lower_dentry(dentry);
1122+ if (willwrite && IS_WRITE_FLAG(file->f_flags) && is_robranch(dentry)) {
1123+ for (bindex = bstart - 1; bindex >= 0; bindex--) {
1124+ err = copyup_file(parent_inode, file, bstart, bindex,
1125+ i_size_read(dentry->d_inode));
1126+ if (!err)
1127+ break;
1128+ }
1129+ atomic_set(&UNIONFS_F(file)->generation,
1130+ atomic_read(&UNIONFS_I(dentry->d_inode)->
1131+ generation));
1132+ goto out;
1133+ }
1134+
1135+ dget(lower_dentry);
1136+ unionfs_mntget(dentry, bstart);
1137+ lower_file = dentry_open(lower_dentry,
1138+ unionfs_lower_mnt_idx(dentry, bstart),
1139+ file->f_flags);
1140+ if (IS_ERR(lower_file)) {
1141+ err = PTR_ERR(lower_file);
1142+ goto out;
1143+ }
1144+ branchget(sb, bstart);
1145+ unionfs_set_lower_file(file, lower_file);
1146+ /* Fix up the position. */
1147+ lower_file->f_pos = file->f_pos;
1148+
1149+ memcpy(&lower_file->f_ra, &file->f_ra, sizeof(struct file_ra_state));
1150+out:
1151+ return err;
1152+}
1153+
1154+/* perform a delayed copyup of a read-write file on a read-only branch */
1155+static int do_delayed_copyup(struct file *file)
1156+{
1157+ int bindex, bstart, bend, err = 0;
1158+ struct dentry *dentry = file->f_path.dentry;
1159+ struct inode *parent_inode = dentry->d_parent->d_inode;
1160+
1161+ bstart = fbstart(file);
1162+ bend = fbend(file);
1163+
1164+ BUG_ON(!S_ISREG(dentry->d_inode->i_mode));
1165+
1166+ unionfs_check_file(file);
1167+ for (bindex = bstart - 1; bindex >= 0; bindex--) {
1168+ if (!d_deleted(dentry))
1169+ err = copyup_file(parent_inode, file, bstart,
1170+ bindex,
1171+ i_size_read(dentry->d_inode));
1172+ else
1173+ err = copyup_deleted_file(file, dentry, bstart,
1174+ bindex);
1175+ /* if succeeded, set lower open-file flags and break */
1176+ if (!err) {
1177+ struct file *lower_file;
1178+ lower_file = unionfs_lower_file_idx(file, bindex);
1179+ lower_file->f_flags = file->f_flags;
1180+ break;
1181+ }
1182+ }
1183+ if (err || (bstart <= fbstart(file)))
1184+ goto out;
1185+ bend = fbend(file);
1186+ for (bindex = bstart; bindex <= bend; bindex++) {
1187+ if (unionfs_lower_file_idx(file, bindex)) {
1188+ branchput(dentry->d_sb, bindex);
1189+ fput(unionfs_lower_file_idx(file, bindex));
1190+ unionfs_set_lower_file_idx(file, bindex, NULL);
1191+ }
1192+ }
1193+ path_put_lowers(dentry, bstart, bend, false);
1194+ iput_lowers(dentry->d_inode, bstart, bend, false);
1195+ /* for reg file, we only open it "once" */
1196+ fbend(file) = fbstart(file);
1197+ dbend(dentry) = dbstart(dentry);
1198+ ibend(dentry->d_inode) = ibstart(dentry->d_inode);
1199+
1200+out:
1201+ unionfs_check_file(file);
1202+ return err;
1203+}
1204+
1205+/*
1206+ * Helper function for unionfs_file_revalidate/locked.
1207+ * Expects dentry/parent to be locked already, and revalidated.
1208+ */
1209+static int __unionfs_file_revalidate(struct file *file, struct dentry *dentry,
1210+ struct super_block *sb, int sbgen,
1211+ int dgen, bool willwrite)
1212+{
1213+ int fgen;
1214+ int bstart, bend, orig_brid;
1215+ int size;
1216+ int err = 0;
1217+
1218+ fgen = atomic_read(&UNIONFS_F(file)->generation);
1219+
1220+ /*
1221+ * There are two cases we are interested in. The first is if the
1222+ * generation is lower than the super-block. The second is if
1223+ * someone has copied up this file from underneath us, we also need
1224+ * to refresh things.
1225+ */
1226+ if (d_deleted(dentry) ||
1227+ (sbgen <= fgen &&
1228+ dbstart(dentry) == fbstart(file) &&
1229+ unionfs_lower_file(file)))
1230+ goto out_may_copyup;
1231+
1232+ /* save orig branch ID */
1233+ orig_brid = UNIONFS_F(file)->saved_branch_ids[fbstart(file)];
1234+
1235+ /* First we throw out the existing files. */
1236+ cleanup_file(file);
1237+
1238+ /* Now we reopen the file(s) as in unionfs_open. */
1239+ bstart = fbstart(file) = dbstart(dentry);
1240+ bend = fbend(file) = dbend(dentry);
1241+
1242+ size = sizeof(struct file *) * sbmax(sb);
1243+ UNIONFS_F(file)->lower_files = kzalloc(size, GFP_KERNEL);
1244+ if (unlikely(!UNIONFS_F(file)->lower_files)) {
1245+ err = -ENOMEM;
1246+ goto out;
1247+ }
1248+ size = sizeof(int) * sbmax(sb);
1249+ UNIONFS_F(file)->saved_branch_ids = kzalloc(size, GFP_KERNEL);
1250+ if (unlikely(!UNIONFS_F(file)->saved_branch_ids)) {
1251+ err = -ENOMEM;
1252+ goto out;
1253+ }
1254+
1255+ if (S_ISDIR(dentry->d_inode->i_mode)) {
1256+ /* We need to open all the files. */
1257+ err = open_all_files(file);
1258+ if (err)
1259+ goto out;
1260+ } else {
1261+ int new_brid;
1262+ /* We only open the highest priority branch. */
1263+ err = open_highest_file(file, willwrite);
1264+ if (err)
1265+ goto out;
1266+ new_brid = UNIONFS_F(file)->saved_branch_ids[fbstart(file)];
1267+ if (unlikely(new_brid != orig_brid && sbgen > fgen)) {
1268+ /*
1269+ * If we re-opened the file on a different branch
1270+ * than the original one, and this was due to a new
1271+ * branch inserted, then update the mnt counts of
1272+ * the old and new branches accordingly.
1273+ */
1274+ unionfs_mntget(dentry, bstart);
1275+ unionfs_mntput(sb->s_root,
1276+ branch_id_to_idx(sb, orig_brid));
1277+ }
1278+ /* regular files have only one open lower file */
1279+ fbend(file) = fbstart(file);
1280+ }
1281+ atomic_set(&UNIONFS_F(file)->generation,
1282+ atomic_read(&UNIONFS_I(dentry->d_inode)->generation));
1283+
1284+out_may_copyup:
1285+ /* Copyup on the first write to a file on a readonly branch. */
1286+ if (willwrite && IS_WRITE_FLAG(file->f_flags) &&
1287+ !IS_WRITE_FLAG(unionfs_lower_file(file)->f_flags) &&
1288+ is_robranch(dentry)) {
1289+ pr_debug("unionfs: do delay copyup of \"%s\"\n",
1290+ dentry->d_name.name);
1291+ err = do_delayed_copyup(file);
1292+ /* regular files have only one open lower file */
1293+ if (!err && !S_ISDIR(dentry->d_inode->i_mode))
1294+ fbend(file) = fbstart(file);
1295+ }
1296+
1297+out:
1298+ if (err) {
1299+ kfree(UNIONFS_F(file)->lower_files);
1300+ kfree(UNIONFS_F(file)->saved_branch_ids);
1301+ } else {
1302+ unionfs_check_file(file);
1303+ }
1304+ return err;
1305+}
1306+
1307+/*
1308+ * Revalidate the struct file
1309+ * @file: file to revalidate
1310+ * @willwrite: true if caller may cause changes to the file; false otherwise.
1311+ * Caller must lock/unlock dentry's branch configuration.
1312+ */
1313+int unionfs_file_revalidate(struct file *file, bool willwrite)
1314+{
1315+ struct super_block *sb;
1316+ struct dentry *dentry;
1317+ int sbgen, dgen;
1318+ int err = 0;
1319+
1320+ dentry = file->f_path.dentry;
1321+ sb = dentry->d_sb;
1322+ verify_locked(dentry);
1323+
1324+ /*
1325+ * First revalidate the dentry inside struct file,
1326+ * but not unhashed dentries.
1327+ */
1328+reval_dentry:
1329+ if (!d_deleted(dentry) &&
1330+ !__unionfs_d_revalidate_chain(dentry, NULL, willwrite)) {
1331+ err = -ESTALE;
1332+ goto out;
1333+ }
1334+
1335+ sbgen = atomic_read(&UNIONFS_SB(sb)->generation);
1336+ dgen = atomic_read(&UNIONFS_D(dentry)->generation);
1337+
1338+ if (unlikely(sbgen > dgen)) {
1339+ pr_debug("unionfs: retry dentry %s revalidation\n",
1340+ dentry->d_name.name);
1341+ schedule();
1342+ goto reval_dentry;
1343+ }
1344+ BUG_ON(sbgen > dgen);
1345+
1346+ err = __unionfs_file_revalidate(file, dentry, sb,
1347+ sbgen, dgen, willwrite);
1348+out:
1349+ return err;
1350+}
1351+
1352+/* same as unionfs_file_revalidate, but parent dentry must be locked too */
1353+int unionfs_file_revalidate_locked(struct file *file, bool willwrite)
1354+{
1355+ struct super_block *sb;
1356+ struct dentry *dentry;
1357+ int sbgen, dgen;
1358+ int err = 0, valid;
1359+
1360+ dentry = file->f_path.dentry;
1361+ sb = dentry->d_sb;
1362+ verify_locked(dentry);
1363+ verify_locked(dentry->d_parent);
1364+
1365+ /* first revalidate (locked) parent, then child */
1366+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, NULL, false);
1367+ if (unlikely(!valid)) {
1368+ err = -ESTALE; /* same as what real_lookup does */
1369+ goto out;
1370+ }
1371+
1372+reval_dentry:
1373+ if (!d_deleted(dentry) &&
1374+ !__unionfs_d_revalidate_one_locked(dentry, NULL, willwrite)) {
1375+ err = -ESTALE;
1376+ goto out;
1377+ }
1378+
1379+ sbgen = atomic_read(&UNIONFS_SB(sb)->generation);
1380+ dgen = atomic_read(&UNIONFS_D(dentry)->generation);
1381+
1382+ if (unlikely(sbgen > dgen)) {
1383+ pr_debug("unionfs: retry (locked) dentry %s revalidation\n",
1384+ dentry->d_name.name);
1385+ schedule();
1386+ goto reval_dentry;
1387+ }
1388+ BUG_ON(sbgen > dgen);
1389+
1390+ err = __unionfs_file_revalidate(file, dentry, sb,
1391+ sbgen, dgen, willwrite);
1392+out:
1393+ return err;
1394+}
1395+
1396+/* unionfs_open helper function: open a directory */
1397+static int __open_dir(struct inode *inode, struct file *file)
1398+{
1399+ struct dentry *lower_dentry;
1400+ struct file *lower_file;
1401+ int bindex, bstart, bend;
1402+ struct vfsmount *mnt;
1403+
1404+ bstart = fbstart(file) = dbstart(file->f_path.dentry);
1405+ bend = fbend(file) = dbend(file->f_path.dentry);
1406+
1407+ for (bindex = bstart; bindex <= bend; bindex++) {
1408+ lower_dentry =
1409+ unionfs_lower_dentry_idx(file->f_path.dentry, bindex);
1410+ if (!lower_dentry)
1411+ continue;
1412+
1413+ dget(lower_dentry);
1414+ unionfs_mntget(file->f_path.dentry, bindex);
1415+ mnt = unionfs_lower_mnt_idx(file->f_path.dentry, bindex);
1416+ lower_file = dentry_open(lower_dentry, mnt, file->f_flags);
1417+ if (IS_ERR(lower_file))
1418+ return PTR_ERR(lower_file);
1419+
1420+ unionfs_set_lower_file_idx(file, bindex, lower_file);
1421+
1422+ /*
1423+ * The branchget goes after the open, because otherwise
1424+ * we would miss the reference on release.
1425+ */
1426+ branchget(inode->i_sb, bindex);
1427+ }
1428+
1429+ return 0;
1430+}
1431+
1432+/* unionfs_open helper function: open a file */
1433+static int __open_file(struct inode *inode, struct file *file)
1434+{
1435+ struct dentry *lower_dentry;
1436+ struct file *lower_file;
1437+ int lower_flags;
1438+ int bindex, bstart, bend;
1439+
1440+ lower_dentry = unionfs_lower_dentry(file->f_path.dentry);
1441+ lower_flags = file->f_flags;
1442+
1443+ bstart = fbstart(file) = dbstart(file->f_path.dentry);
1444+ bend = fbend(file) = dbend(file->f_path.dentry);
1445+
1446+ /*
1447+ * check for the permission for lower file. If the error is
1448+ * COPYUP_ERR, copyup the file.
1449+ */
1450+ if (lower_dentry->d_inode && is_robranch(file->f_path.dentry)) {
1451+ /*
1452+ * if the open will change the file, copy it up otherwise
1453+ * defer it.
1454+ */
1455+ if (lower_flags & O_TRUNC) {
1456+ int size = 0;
1457+ int err = -EROFS;
1458+
1459+ /* copyup the file */
1460+ for (bindex = bstart - 1; bindex >= 0; bindex--) {
1461+ err = copyup_file(
1462+ file->f_path.dentry->d_parent->d_inode,
1463+ file, bstart, bindex, size);
1464+ if (!err)
1465+ break;
1466+ }
1467+ return err;
1468+ } else {
1469+ /*
1470+ * turn off writeable flags, to force delayed copyup
1471+ * by caller.
1472+ */
1473+ lower_flags &= ~(OPEN_WRITE_FLAGS);
1474+ }
1475+ }
1476+
1477+ dget(lower_dentry);
1478+
1479+ /*
1480+ * dentry_open will decrement mnt refcnt if err.
1481+ * otherwise fput() will do an mntput() for us upon file close.
1482+ */
1483+ unionfs_mntget(file->f_path.dentry, bstart);
1484+ lower_file =
1485+ dentry_open(lower_dentry,
1486+ unionfs_lower_mnt_idx(file->f_path.dentry, bstart),
1487+ lower_flags);
1488+ if (IS_ERR(lower_file))
1489+ return PTR_ERR(lower_file);
1490+
1491+ unionfs_set_lower_file(file, lower_file);
1492+ branchget(inode->i_sb, bstart);
1493+
1494+ return 0;
1495+}
1496+
1497+int unionfs_open(struct inode *inode, struct file *file)
1498+{
1499+ int err = 0;
1500+ struct file *lower_file = NULL;
1501+ struct dentry *dentry = file->f_path.dentry;
1502+ int bindex = 0, bstart = 0, bend = 0;
1503+ int size;
1504+ int valid = 0;
1505+
1506+ unionfs_read_lock(inode->i_sb, UNIONFS_SMUTEX_PARENT);
1507+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
1508+ if (dentry != dentry->d_parent)
1509+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT);
1510+
1511+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, NULL, false);
1512+ if (unlikely(!valid)) {
1513+ err = -ESTALE;
1514+ goto out_nofree;
1515+ }
1516+
1517+ file->private_data =
1518+ kzalloc(sizeof(struct unionfs_file_info), GFP_KERNEL);
1519+ if (unlikely(!UNIONFS_F(file))) {
1520+ err = -ENOMEM;
1521+ goto out_nofree;
1522+ }
1523+ fbstart(file) = -1;
1524+ fbend(file) = -1;
1525+ atomic_set(&UNIONFS_F(file)->generation,
1526+ atomic_read(&UNIONFS_I(inode)->generation));
1527+
1528+ size = sizeof(struct file *) * sbmax(inode->i_sb);
1529+ UNIONFS_F(file)->lower_files = kzalloc(size, GFP_KERNEL);
1530+ if (unlikely(!UNIONFS_F(file)->lower_files)) {
1531+ err = -ENOMEM;
1532+ goto out;
1533+ }
1534+ size = sizeof(int) * sbmax(inode->i_sb);
1535+ UNIONFS_F(file)->saved_branch_ids = kzalloc(size, GFP_KERNEL);
1536+ if (unlikely(!UNIONFS_F(file)->saved_branch_ids)) {
1537+ err = -ENOMEM;
1538+ goto out;
1539+ }
1540+
1541+ bstart = fbstart(file) = dbstart(dentry);
1542+ bend = fbend(file) = dbend(dentry);
1543+
1544+ /*
1545+ * open all directories and make the unionfs file struct point to
1546+ * these lower file structs
1547+ */
1548+ if (S_ISDIR(inode->i_mode))
1549+ err = __open_dir(inode, file); /* open a dir */
1550+ else
1551+ err = __open_file(inode, file); /* open a file */
1552+
1553+ /* freeing the allocated resources, and fput the opened files */
1554+ if (err) {
1555+ for (bindex = bstart; bindex <= bend; bindex++) {
1556+ lower_file = unionfs_lower_file_idx(file, bindex);
1557+ if (!lower_file)
1558+ continue;
1559+
1560+ branchput(dentry->d_sb, bindex);
1561+ /* fput calls dput for lower_dentry */
1562+ fput(lower_file);
1563+ }
1564+ }
1565+
1566+out:
1567+ if (err) {
1568+ kfree(UNIONFS_F(file)->lower_files);
1569+ kfree(UNIONFS_F(file)->saved_branch_ids);
1570+ kfree(UNIONFS_F(file));
1571+ }
1572+out_nofree:
1573+ if (!err) {
1574+ unionfs_postcopyup_setmnt(dentry);
1575+ unionfs_copy_attr_times(inode);
1576+ unionfs_check_file(file);
1577+ unionfs_check_inode(inode);
1578+ }
1579+ if (dentry != dentry->d_parent)
1580+ unionfs_unlock_dentry(dentry->d_parent);
1581+ unionfs_unlock_dentry(dentry);
1582+ unionfs_read_unlock(inode->i_sb);
1583+ return err;
1584+}
1585+
1586+/*
1587+ * release all lower object references & free the file info structure
1588+ *
1589+ * No need to grab sb info's rwsem.
1590+ */
1591+int unionfs_file_release(struct inode *inode, struct file *file)
1592+{
1593+ struct file *lower_file = NULL;
1594+ struct unionfs_file_info *fileinfo;
1595+ struct unionfs_inode_info *inodeinfo;
1596+ struct super_block *sb = inode->i_sb;
1597+ struct dentry *dentry = file->f_path.dentry;
1598+ int bindex, bstart, bend;
1599+ int fgen, err = 0;
1600+
1601+ unionfs_read_lock(sb, UNIONFS_SMUTEX_PARENT);
1602+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
1603+
1604+ /*
1605+ * Yes, we have to revalidate this file even if it's being released.
1606+ * This is important for open-but-unlinked files, as well as mmap
1607+ * support.
1608+ */
1609+ err = unionfs_file_revalidate(file, UNIONFS_F(file)->wrote_to_file);
1610+ if (unlikely(err))
1611+ goto out;
1612+ unionfs_check_file(file);
1613+ fileinfo = UNIONFS_F(file);
1614+ BUG_ON(file->f_path.dentry->d_inode != inode);
1615+ inodeinfo = UNIONFS_I(inode);
1616+
1617+ /* fput all the lower files */
1618+ fgen = atomic_read(&fileinfo->generation);
1619+ bstart = fbstart(file);
1620+ bend = fbend(file);
1621+
1622+ for (bindex = bstart; bindex <= bend; bindex++) {
1623+ lower_file = unionfs_lower_file_idx(file, bindex);
1624+
1625+ if (lower_file) {
1626+ unionfs_set_lower_file_idx(file, bindex, NULL);
1627+ fput(lower_file);
1628+ branchput(sb, bindex);
1629+ }
1630+
1631+ /* if there are no more refs to the dentry, dput it */
1632+ if (d_deleted(dentry)) {
1633+ dput(unionfs_lower_dentry_idx(dentry, bindex));
1634+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
1635+ }
1636+ }
1637+
1638+ kfree(fileinfo->lower_files);
1639+ kfree(fileinfo->saved_branch_ids);
1640+
1641+ if (fileinfo->rdstate) {
1642+ fileinfo->rdstate->access = jiffies;
1643+ spin_lock(&inodeinfo->rdlock);
1644+ inodeinfo->rdcount++;
1645+ list_add_tail(&fileinfo->rdstate->cache,
1646+ &inodeinfo->readdircache);
1647+ mark_inode_dirty(inode);
1648+ spin_unlock(&inodeinfo->rdlock);
1649+ fileinfo->rdstate = NULL;
1650+ }
1651+ kfree(fileinfo);
1652+
1653+out:
1654+ unionfs_unlock_dentry(dentry);
1655+ unionfs_read_unlock(sb);
1656+ return err;
1657+}
1658+
1659+/* pass the ioctl to the lower fs */
1660+static long do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1661+{
1662+ struct file *lower_file;
1663+ int err;
1664+
1665+ lower_file = unionfs_lower_file(file);
1666+
1667+ err = -ENOTTY;
1668+ if (!lower_file || !lower_file->f_op)
1669+ goto out;
1670+ if (lower_file->f_op->unlocked_ioctl) {
1671+ err = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg);
1672+ } else if (lower_file->f_op->ioctl) {
1673+ lock_kernel();
1674+ err = lower_file->f_op->ioctl(
1675+ lower_file->f_path.dentry->d_inode,
1676+ lower_file, cmd, arg);
1677+ unlock_kernel();
1678+ }
1679+
1680+out:
1681+ return err;
1682+}
1683+
1684+/*
1685+ * return to user-space the branch indices containing the file in question
1686+ *
1687+ * We use fd_set and therefore we are limited to the number of the branches
1688+ * to FD_SETSIZE, which is currently 1024 - plenty for most people
1689+ */
1690+static int unionfs_ioctl_queryfile(struct file *file, unsigned int cmd,
1691+ unsigned long arg)
1692+{
1693+ int err = 0;
1694+ fd_set branchlist;
1695+ int bstart = 0, bend = 0, bindex = 0;
1696+ int orig_bstart, orig_bend;
1697+ struct dentry *dentry, *lower_dentry;
1698+ struct vfsmount *mnt;
1699+
1700+ dentry = file->f_path.dentry;
1701+ orig_bstart = dbstart(dentry);
1702+ orig_bend = dbend(dentry);
1703+ err = unionfs_partial_lookup(dentry);
1704+ if (err)
1705+ goto out;
1706+ bstart = dbstart(dentry);
1707+ bend = dbend(dentry);
1708+
1709+ FD_ZERO(&branchlist);
1710+
1711+ for (bindex = bstart; bindex <= bend; bindex++) {
1712+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
1713+ if (!lower_dentry)
1714+ continue;
1715+ if (likely(lower_dentry->d_inode))
1716+ FD_SET(bindex, &branchlist);
1717+ /* purge any lower objects after partial_lookup */
1718+ if (bindex < orig_bstart || bindex > orig_bend) {
1719+ dput(lower_dentry);
1720+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
1721+ iput(unionfs_lower_inode_idx(dentry->d_inode, bindex));
1722+ unionfs_set_lower_inode_idx(dentry->d_inode, bindex,
1723+ NULL);
1724+ mnt = unionfs_lower_mnt_idx(dentry, bindex);
1725+ if (!mnt)
1726+ continue;
1727+ unionfs_mntput(dentry, bindex);
1728+ unionfs_set_lower_mnt_idx(dentry, bindex, NULL);
1729+ }
1730+ }
1731+ /* restore original dentry's offsets */
1732+ dbstart(dentry) = orig_bstart;
1733+ dbend(dentry) = orig_bend;
1734+ ibstart(dentry->d_inode) = orig_bstart;
1735+ ibend(dentry->d_inode) = orig_bend;
1736+
1737+ err = copy_to_user((void __user *)arg, &branchlist, sizeof(fd_set));
1738+ if (unlikely(err))
1739+ err = -EFAULT;
1740+
1741+out:
1742+ return err < 0 ? err : bend;
1743+}
1744+
1745+long unionfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1746+{
1747+ long err;
1748+ struct dentry *dentry = file->f_path.dentry;
1749+
1750+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
1751+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
1752+
1753+ err = unionfs_file_revalidate(file, true);
1754+ if (unlikely(err))
1755+ goto out;
1756+
1757+ /* check if asked for local commands */
1758+ switch (cmd) {
1759+ case UNIONFS_IOCTL_INCGEN:
1760+ /* Increment the superblock generation count */
1761+ pr_info("unionfs: incgen ioctl deprecated; "
1762+ "use \"-o remount,incgen\"\n");
1763+ err = -ENOSYS;
1764+ break;
1765+
1766+ case UNIONFS_IOCTL_QUERYFILE:
1767+ /* Return list of branches containing the given file */
1768+ err = unionfs_ioctl_queryfile(file, cmd, arg);
1769+ break;
1770+
1771+ default:
1772+ /* pass the ioctl down */
1773+ err = do_ioctl(file, cmd, arg);
1774+ break;
1775+ }
1776+
1777+out:
1778+ unionfs_check_file(file);
1779+ unionfs_unlock_dentry(dentry);
1780+ unionfs_read_unlock(dentry->d_sb);
1781+ return err;
1782+}
1783+
1784+int unionfs_flush(struct file *file, fl_owner_t id)
1785+{
1786+ int err = 0;
1787+ struct file *lower_file = NULL;
1788+ struct dentry *dentry = file->f_path.dentry;
1789+ int bindex, bstart, bend;
1790+
1791+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
1792+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
1793+
1794+ err = unionfs_file_revalidate(file, UNIONFS_F(file)->wrote_to_file);
1795+ if (unlikely(err))
1796+ goto out;
1797+ unionfs_check_file(file);
1798+
1799+ bstart = fbstart(file);
1800+ bend = fbend(file);
1801+ for (bindex = bstart; bindex <= bend; bindex++) {
1802+ lower_file = unionfs_lower_file_idx(file, bindex);
1803+
1804+ if (lower_file && lower_file->f_op &&
1805+ lower_file->f_op->flush) {
1806+ err = lower_file->f_op->flush(lower_file, id);
1807+ if (err)
1808+ goto out;
1809+ }
1810+
1811+ }
1812+
1813+out:
1814+ if (!err)
1815+ unionfs_check_file(file);
1816+ unionfs_unlock_dentry(dentry);
1817+ unionfs_read_unlock(dentry->d_sb);
1818+ return err;
1819+}
1820diff --git a/fs/unionfs/copyup.c b/fs/unionfs/copyup.c
1821new file mode 100644
1822index 0000000..ae6ea2b
1823--- /dev/null
1824+++ b/fs/unionfs/copyup.c
1825@@ -0,0 +1,879 @@
1826+/*
1827+ * Copyright (c) 2003-2008 Erez Zadok
1828+ * Copyright (c) 2003-2006 Charles P. Wright
1829+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
1830+ * Copyright (c) 2005-2006 Junjiro Okajima
1831+ * Copyright (c) 2005 Arun M. Krishnakumar
1832+ * Copyright (c) 2004-2006 David P. Quigley
1833+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
1834+ * Copyright (c) 2003 Puja Gupta
1835+ * Copyright (c) 2003 Harikesavan Krishnan
1836+ * Copyright (c) 2003-2008 Stony Brook University
1837+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
1838+ *
1839+ * This program is free software; you can redistribute it and/or modify
1840+ * it under the terms of the GNU General Public License version 2 as
1841+ * published by the Free Software Foundation.
1842+ */
1843+
1844+#include "union.h"
1845+
1846+/*
1847+ * For detailed explanation of copyup see:
1848+ * Documentation/filesystems/unionfs/concepts.txt
1849+ */
1850+
1851+#ifdef CONFIG_UNION_FS_XATTR
1852+/* copyup all extended attrs for a given dentry */
1853+static int copyup_xattrs(struct dentry *old_lower_dentry,
1854+ struct dentry *new_lower_dentry)
1855+{
1856+ int err = 0;
1857+ ssize_t list_size = -1;
1858+ char *name_list = NULL;
1859+ char *attr_value = NULL;
1860+ char *name_list_buf = NULL;
1861+
1862+ /* query the actual size of the xattr list */
1863+ list_size = vfs_listxattr(old_lower_dentry, NULL, 0);
1864+ if (list_size <= 0) {
1865+ err = list_size;
1866+ goto out;
1867+ }
1868+
1869+ /* allocate space for the actual list */
1870+ name_list = unionfs_xattr_alloc(list_size + 1, XATTR_LIST_MAX);
1871+ if (unlikely(!name_list || IS_ERR(name_list))) {
1872+ err = PTR_ERR(name_list);
1873+ goto out;
1874+ }
1875+
1876+ name_list_buf = name_list; /* save for kfree at end */
1877+
1878+ /* now get the actual xattr list of the source file */
1879+ list_size = vfs_listxattr(old_lower_dentry, name_list, list_size);
1880+ if (list_size <= 0) {
1881+ err = list_size;
1882+ goto out;
1883+ }
1884+
1885+ /* allocate space to hold each xattr's value */
1886+ attr_value = unionfs_xattr_alloc(XATTR_SIZE_MAX, XATTR_SIZE_MAX);
1887+ if (unlikely(!attr_value || IS_ERR(attr_value))) {
1888+ err = PTR_ERR(name_list);
1889+ goto out;
1890+ }
1891+
1892+ /* in a loop, get and set each xattr from src to dst file */
1893+ while (*name_list) {
1894+ ssize_t size;
1895+
1896+ /* Lock here since vfs_getxattr doesn't lock for us */
1897+ mutex_lock(&old_lower_dentry->d_inode->i_mutex);
1898+ size = vfs_getxattr(old_lower_dentry, name_list,
1899+ attr_value, XATTR_SIZE_MAX);
1900+ mutex_unlock(&old_lower_dentry->d_inode->i_mutex);
1901+ if (size < 0) {
1902+ err = size;
1903+ goto out;
1904+ }
1905+ if (size > XATTR_SIZE_MAX) {
1906+ err = -E2BIG;
1907+ goto out;
1908+ }
1909+ /* Don't lock here since vfs_setxattr does it for us. */
1910+ err = vfs_setxattr(new_lower_dentry, name_list, attr_value,
1911+ size, 0);
1912+ /*
1913+ * Selinux depends on "security.*" xattrs, so to maintain
1914+ * the security of copied-up files, if Selinux is active,
1915+ * then we must copy these xattrs as well. So we need to
1916+ * temporarily get FOWNER privileges.
1917+ * XXX: move entire copyup code to SIOQ.
1918+ */
1919+ if (err == -EPERM && !capable(CAP_FOWNER)) {
1920+ cap_raise(current->cap_effective, CAP_FOWNER);
1921+ err = vfs_setxattr(new_lower_dentry, name_list,
1922+ attr_value, size, 0);
1923+ cap_lower(current->cap_effective, CAP_FOWNER);
1924+ }
1925+ if (err < 0)
1926+ goto out;
1927+ name_list += strlen(name_list) + 1;
1928+ }
1929+out:
1930+ unionfs_xattr_kfree(name_list_buf);
1931+ unionfs_xattr_kfree(attr_value);
1932+ /* Ignore if xattr isn't supported */
1933+ if (err == -ENOTSUPP || err == -EOPNOTSUPP)
1934+ err = 0;
1935+ return err;
1936+}
1937+#endif /* CONFIG_UNION_FS_XATTR */
1938+
1939+/*
1940+ * Determine the mode based on the copyup flags, and the existing dentry.
1941+ *
1942+ * Handle file systems which may not support certain options. For example
1943+ * jffs2 doesn't allow one to chmod a symlink. So we ignore such harmless
1944+ * errors, rather than propagating them up, which results in copyup errors
1945+ * and errors returned back to users.
1946+ */
1947+static int copyup_permissions(struct super_block *sb,
1948+ struct dentry *old_lower_dentry,
1949+ struct dentry *new_lower_dentry)
1950+{
1951+ struct inode *i = old_lower_dentry->d_inode;
1952+ struct iattr newattrs;
1953+ int err;
1954+
1955+ newattrs.ia_atime = i->i_atime;
1956+ newattrs.ia_mtime = i->i_mtime;
1957+ newattrs.ia_ctime = i->i_ctime;
1958+ newattrs.ia_gid = i->i_gid;
1959+ newattrs.ia_uid = i->i_uid;
1960+ newattrs.ia_valid = ATTR_CTIME | ATTR_ATIME | ATTR_MTIME |
1961+ ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_FORCE |
1962+ ATTR_GID | ATTR_UID;
1963+ mutex_lock(&new_lower_dentry->d_inode->i_mutex);
1964+ err = notify_change(new_lower_dentry, &newattrs);
1965+ if (err)
1966+ goto out;
1967+
1968+ /* now try to change the mode and ignore EOPNOTSUPP on symlinks */
1969+ newattrs.ia_mode = i->i_mode;
1970+ newattrs.ia_valid = ATTR_MODE | ATTR_FORCE;
1971+ err = notify_change(new_lower_dentry, &newattrs);
1972+ if (err == -EOPNOTSUPP &&
1973+ S_ISLNK(new_lower_dentry->d_inode->i_mode)) {
1974+ printk(KERN_WARNING
1975+ "unionfs: changing \"%s\" symlink mode unsupported\n",
1976+ new_lower_dentry->d_name.name);
1977+ err = 0;
1978+ }
1979+
1980+out:
1981+ mutex_unlock(&new_lower_dentry->d_inode->i_mutex);
1982+ return err;
1983+}
1984+
1985+/*
1986+ * create the new device/file/directory - use copyup_permission to copyup
1987+ * times, and mode
1988+ *
1989+ * if the object being copied up is a regular file, the file is only created,
1990+ * the contents have to be copied up separately
1991+ */
1992+static int __copyup_ndentry(struct dentry *old_lower_dentry,
1993+ struct dentry *new_lower_dentry,
1994+ struct dentry *new_lower_parent_dentry,
1995+ char *symbuf)
1996+{
1997+ int err = 0;
1998+ umode_t old_mode = old_lower_dentry->d_inode->i_mode;
1999+ struct sioq_args args;
2000+
2001+ if (S_ISDIR(old_mode)) {
2002+ args.mkdir.parent = new_lower_parent_dentry->d_inode;
2003+ args.mkdir.dentry = new_lower_dentry;
2004+ args.mkdir.mode = old_mode;
2005+
2006+ run_sioq(__unionfs_mkdir, &args);
2007+ err = args.err;
2008+ } else if (S_ISLNK(old_mode)) {
2009+ args.symlink.parent = new_lower_parent_dentry->d_inode;
2010+ args.symlink.dentry = new_lower_dentry;
2011+ args.symlink.symbuf = symbuf;
2012+
2013+ run_sioq(__unionfs_symlink, &args);
2014+ err = args.err;
2015+ } else if (S_ISBLK(old_mode) || S_ISCHR(old_mode) ||
2016+ S_ISFIFO(old_mode) || S_ISSOCK(old_mode)) {
2017+ args.mknod.parent = new_lower_parent_dentry->d_inode;
2018+ args.mknod.dentry = new_lower_dentry;
2019+ args.mknod.mode = old_mode;
2020+ args.mknod.dev = old_lower_dentry->d_inode->i_rdev;
2021+
2022+ run_sioq(__unionfs_mknod, &args);
2023+ err = args.err;
2024+ } else if (S_ISREG(old_mode)) {
2025+ struct nameidata nd;
2026+ err = init_lower_nd(&nd, LOOKUP_CREATE);
2027+ if (unlikely(err < 0))
2028+ goto out;
2029+ args.create.nd = &nd;
2030+ args.create.parent = new_lower_parent_dentry->d_inode;
2031+ args.create.dentry = new_lower_dentry;
2032+ args.create.mode = old_mode;
2033+
2034+ run_sioq(__unionfs_create, &args);
2035+ err = args.err;
2036+ release_lower_nd(&nd, err);
2037+ } else {
2038+ printk(KERN_CRIT "unionfs: unknown inode type %d\n",
2039+ old_mode);
2040+ BUG();
2041+ }
2042+
2043+out:
2044+ return err;
2045+}
2046+
2047+static int __copyup_reg_data(struct dentry *dentry,
2048+ struct dentry *new_lower_dentry, int new_bindex,
2049+ struct dentry *old_lower_dentry, int old_bindex,
2050+ struct file **copyup_file, loff_t len)
2051+{
2052+ struct super_block *sb = dentry->d_sb;
2053+ struct file *input_file;
2054+ struct file *output_file;
2055+ struct vfsmount *output_mnt;
2056+ mm_segment_t old_fs;
2057+ char *buf = NULL;
2058+ ssize_t read_bytes, write_bytes;
2059+ loff_t size;
2060+ int err = 0;
2061+
2062+ /* open old file */
2063+ unionfs_mntget(dentry, old_bindex);
2064+ branchget(sb, old_bindex);
2065+ /* dentry_open calls dput and mntput if it returns an error */
2066+ input_file = dentry_open(old_lower_dentry,
2067+ unionfs_lower_mnt_idx(dentry, old_bindex),
2068+ O_RDONLY | O_LARGEFILE);
2069+ if (IS_ERR(input_file)) {
2070+ dput(old_lower_dentry);
2071+ err = PTR_ERR(input_file);
2072+ goto out;
2073+ }
2074+ if (unlikely(!input_file->f_op || !input_file->f_op->read)) {
2075+ err = -EINVAL;
2076+ goto out_close_in;
2077+ }
2078+
2079+ /* open new file */
2080+ dget(new_lower_dentry);
2081+ output_mnt = unionfs_mntget(sb->s_root, new_bindex);
2082+ branchget(sb, new_bindex);
2083+ output_file = dentry_open(new_lower_dentry, output_mnt,
2084+ O_RDWR | O_LARGEFILE);
2085+ if (IS_ERR(output_file)) {
2086+ err = PTR_ERR(output_file);
2087+ goto out_close_in2;
2088+ }
2089+ if (unlikely(!output_file->f_op || !output_file->f_op->write)) {
2090+ err = -EINVAL;
2091+ goto out_close_out;
2092+ }
2093+
2094+ /* allocating a buffer */
2095+ buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
2096+ if (unlikely(!buf)) {
2097+ err = -ENOMEM;
2098+ goto out_close_out;
2099+ }
2100+
2101+ input_file->f_pos = 0;
2102+ output_file->f_pos = 0;
2103+
2104+ old_fs = get_fs();
2105+ set_fs(KERNEL_DS);
2106+
2107+ size = len;
2108+ err = 0;
2109+ do {
2110+ if (len >= PAGE_SIZE)
2111+ size = PAGE_SIZE;
2112+ else if ((len < PAGE_SIZE) && (len > 0))
2113+ size = len;
2114+
2115+ len -= PAGE_SIZE;
2116+
2117+ read_bytes =
2118+ input_file->f_op->read(input_file,
2119+ (char __user *)buf, size,
2120+ &input_file->f_pos);
2121+ if (read_bytes <= 0) {
2122+ err = read_bytes;
2123+ break;
2124+ }
2125+
2126+ /* see Documentation/filesystems/unionfs/issues.txt */
2127+ lockdep_off();
2128+ write_bytes =
2129+ output_file->f_op->write(output_file,
2130+ (char __user *)buf,
2131+ read_bytes,
2132+ &output_file->f_pos);
2133+ lockdep_on();
2134+ if ((write_bytes < 0) || (write_bytes < read_bytes)) {
2135+ err = write_bytes;
2136+ break;
2137+ }
2138+ } while ((read_bytes > 0) && (len > 0));
2139+
2140+ set_fs(old_fs);
2141+
2142+ kfree(buf);
2143+
2144+ if (!err)
2145+ err = output_file->f_op->fsync(output_file,
2146+ new_lower_dentry, 0);
2147+
2148+ if (err)
2149+ goto out_close_out;
2150+
2151+ if (copyup_file) {
2152+ *copyup_file = output_file;
2153+ goto out_close_in;
2154+ }
2155+
2156+out_close_out:
2157+ fput(output_file);
2158+
2159+out_close_in2:
2160+ branchput(sb, new_bindex);
2161+
2162+out_close_in:
2163+ fput(input_file);
2164+
2165+out:
2166+ branchput(sb, old_bindex);
2167+
2168+ return err;
2169+}
2170+
2171+/*
2172+ * dput the lower references for old and new dentry & clear a lower dentry
2173+ * pointer
2174+ */
2175+static void __clear(struct dentry *dentry, struct dentry *old_lower_dentry,
2176+ int old_bstart, int old_bend,
2177+ struct dentry *new_lower_dentry, int new_bindex)
2178+{
2179+ /* get rid of the lower dentry and all its traces */
2180+ unionfs_set_lower_dentry_idx(dentry, new_bindex, NULL);
2181+ dbstart(dentry) = old_bstart;
2182+ dbend(dentry) = old_bend;
2183+
2184+ dput(new_lower_dentry);
2185+ dput(old_lower_dentry);
2186+}
2187+
2188+/*
2189+ * Copy up a dentry to a file of specified name.
2190+ *
2191+ * @dir: used to pull the ->i_sb to access other branches
2192+ * @dentry: the non-negative dentry whose lower_inode we should copy
2193+ * @bstart: the branch of the lower_inode to copy from
2194+ * @new_bindex: the branch to create the new file in
2195+ * @name: the name of the file to create
2196+ * @namelen: length of @name
2197+ * @copyup_file: the "struct file" to return (optional)
2198+ * @len: how many bytes to copy-up?
2199+ */
2200+int copyup_dentry(struct inode *dir, struct dentry *dentry, int bstart,
2201+ int new_bindex, const char *name, int namelen,
2202+ struct file **copyup_file, loff_t len)
2203+{
2204+ struct dentry *new_lower_dentry;
2205+ struct dentry *old_lower_dentry = NULL;
2206+ struct super_block *sb;
2207+ int err = 0;
2208+ int old_bindex;
2209+ int old_bstart;
2210+ int old_bend;
2211+ struct dentry *new_lower_parent_dentry = NULL;
2212+ mm_segment_t oldfs;
2213+ char *symbuf = NULL;
2214+
2215+ verify_locked(dentry);
2216+
2217+ old_bindex = bstart;
2218+ old_bstart = dbstart(dentry);
2219+ old_bend = dbend(dentry);
2220+
2221+ BUG_ON(new_bindex < 0);
2222+ BUG_ON(new_bindex >= old_bindex);
2223+
2224+ sb = dir->i_sb;
2225+
2226+ err = is_robranch_super(sb, new_bindex);
2227+ if (err)
2228+ goto out;
2229+
2230+ /* Create the directory structure above this dentry. */
2231+ new_lower_dentry = create_parents(dir, dentry, name, new_bindex);
2232+ if (IS_ERR(new_lower_dentry)) {
2233+ err = PTR_ERR(new_lower_dentry);
2234+ goto out;
2235+ }
2236+
2237+ old_lower_dentry = unionfs_lower_dentry_idx(dentry, old_bindex);
2238+ /* we conditionally dput this old_lower_dentry at end of function */
2239+ dget(old_lower_dentry);
2240+
2241+ /* For symlinks, we must read the link before we lock the directory. */
2242+ if (S_ISLNK(old_lower_dentry->d_inode->i_mode)) {
2243+
2244+ symbuf = kmalloc(PATH_MAX, GFP_KERNEL);
2245+ if (unlikely(!symbuf)) {
2246+ __clear(dentry, old_lower_dentry,
2247+ old_bstart, old_bend,
2248+ new_lower_dentry, new_bindex);
2249+ err = -ENOMEM;
2250+ goto out_free;
2251+ }
2252+
2253+ oldfs = get_fs();
2254+ set_fs(KERNEL_DS);
2255+ err = old_lower_dentry->d_inode->i_op->readlink(
2256+ old_lower_dentry,
2257+ (char __user *)symbuf,
2258+ PATH_MAX);
2259+ set_fs(oldfs);
2260+ if (err < 0) {
2261+ __clear(dentry, old_lower_dentry,
2262+ old_bstart, old_bend,
2263+ new_lower_dentry, new_bindex);
2264+ goto out_free;
2265+ }
2266+ symbuf[err] = '\0';
2267+ }
2268+
2269+ /* Now we lock the parent, and create the object in the new branch. */
2270+ new_lower_parent_dentry = lock_parent(new_lower_dentry);
2271+
2272+ /* create the new inode */
2273+ err = __copyup_ndentry(old_lower_dentry, new_lower_dentry,
2274+ new_lower_parent_dentry, symbuf);
2275+
2276+ if (err) {
2277+ __clear(dentry, old_lower_dentry,
2278+ old_bstart, old_bend,
2279+ new_lower_dentry, new_bindex);
2280+ goto out_unlock;
2281+ }
2282+
2283+ /* We actually copyup the file here. */
2284+ if (S_ISREG(old_lower_dentry->d_inode->i_mode))
2285+ err = __copyup_reg_data(dentry, new_lower_dentry, new_bindex,
2286+ old_lower_dentry, old_bindex,
2287+ copyup_file, len);
2288+ if (err)
2289+ goto out_unlink;
2290+
2291+ /* Set permissions. */
2292+ err = copyup_permissions(sb, old_lower_dentry, new_lower_dentry);
2293+ if (err)
2294+ goto out_unlink;
2295+
2296+#ifdef CONFIG_UNION_FS_XATTR
2297+ /* Selinux uses extended attributes for permissions. */
2298+ err = copyup_xattrs(old_lower_dentry, new_lower_dentry);
2299+ if (err)
2300+ goto out_unlink;
2301+#endif /* CONFIG_UNION_FS_XATTR */
2302+
2303+ /* do not allow files getting deleted to be re-interposed */
2304+ if (!d_deleted(dentry))
2305+ unionfs_reinterpose(dentry);
2306+
2307+ goto out_unlock;
2308+
2309+out_unlink:
2310+ /*
2311+ * copyup failed, because we possibly ran out of space or
2312+ * quota, or something else happened so let's unlink; we don't
2313+ * really care about the return value of vfs_unlink
2314+ */
2315+ vfs_unlink(new_lower_parent_dentry->d_inode, new_lower_dentry);
2316+
2317+ if (copyup_file) {
2318+ /* need to close the file */
2319+
2320+ fput(*copyup_file);
2321+ branchput(sb, new_bindex);
2322+ }
2323+
2324+ /*
2325+ * TODO: should we reset the error to something like -EIO?
2326+ *
2327+ * If we don't reset, the user may get some nonsensical errors, but
2328+ * on the other hand, if we reset to EIO, we guarantee that the user
2329+ * will get a "confusing" error message.
2330+ */
2331+
2332+out_unlock:
2333+ unlock_dir(new_lower_parent_dentry);
2334+
2335+out_free:
2336+ /*
2337+ * If old_lower_dentry was not a file, then we need to dput it. If
2338+ * it was a file, then it was already dput indirectly by other
2339+ * functions we call above which operate on regular files.
2340+ */
2341+ if (old_lower_dentry && old_lower_dentry->d_inode &&
2342+ !S_ISREG(old_lower_dentry->d_inode->i_mode))
2343+ dput(old_lower_dentry);
2344+ kfree(symbuf);
2345+
2346+ if (err)
2347+ goto out;
2348+ if (!S_ISDIR(dentry->d_inode->i_mode)) {
2349+ unionfs_postcopyup_release(dentry);
2350+ if (!unionfs_lower_inode(dentry->d_inode)) {
2351+ /*
2352+ * If we got here, then we copied up to an
2353+ * unlinked-open file, whose name is .unionfsXXXXX.
2354+ */
2355+ struct inode *inode = new_lower_dentry->d_inode;
2356+ atomic_inc(&inode->i_count);
2357+ unionfs_set_lower_inode_idx(dentry->d_inode,
2358+ ibstart(dentry->d_inode),
2359+ inode);
2360+ }
2361+ }
2362+ unionfs_postcopyup_setmnt(dentry);
2363+ /* sync inode times from copied-up inode to our inode */
2364+ unionfs_copy_attr_times(dentry->d_inode);
2365+ unionfs_check_inode(dir);
2366+ unionfs_check_dentry(dentry);
2367+out:
2368+ return err;
2369+}
2370+
2371+/*
2372+ * This function creates a copy of a file represented by 'file' which
2373+ * currently resides in branch 'bstart' to branch 'new_bindex.' The copy
2374+ * will be named "name".
2375+ */
2376+int copyup_named_file(struct inode *dir, struct file *file, char *name,
2377+ int bstart, int new_bindex, loff_t len)
2378+{
2379+ int err = 0;
2380+ struct file *output_file = NULL;
2381+
2382+ err = copyup_dentry(dir, file->f_path.dentry, bstart, new_bindex,
2383+ name, strlen(name), &output_file, len);
2384+ if (!err) {
2385+ fbstart(file) = new_bindex;
2386+ unionfs_set_lower_file_idx(file, new_bindex, output_file);
2387+ }
2388+
2389+ return err;
2390+}
2391+
2392+/*
2393+ * This function creates a copy of a file represented by 'file' which
2394+ * currently resides in branch 'bstart' to branch 'new_bindex'.
2395+ */
2396+int copyup_file(struct inode *dir, struct file *file, int bstart,
2397+ int new_bindex, loff_t len)
2398+{
2399+ int err = 0;
2400+ struct file *output_file = NULL;
2401+ struct dentry *dentry = file->f_path.dentry;
2402+
2403+ err = copyup_dentry(dir, dentry, bstart, new_bindex,
2404+ dentry->d_name.name, dentry->d_name.len,
2405+ &output_file, len);
2406+ if (!err) {
2407+ fbstart(file) = new_bindex;
2408+ unionfs_set_lower_file_idx(file, new_bindex, output_file);
2409+ }
2410+
2411+ return err;
2412+}
2413+
2414+/* purge a dentry's lower-branch states (dput/mntput, etc.) */
2415+static void __cleanup_dentry(struct dentry *dentry, int bindex,
2416+ int old_bstart, int old_bend)
2417+{
2418+ int loop_start;
2419+ int loop_end;
2420+ int new_bstart = -1;
2421+ int new_bend = -1;
2422+ int i;
2423+
2424+ loop_start = min(old_bstart, bindex);
2425+ loop_end = max(old_bend, bindex);
2426+
2427+ /*
2428+ * This loop sets the bstart and bend for the new dentry by
2429+ * traversing from left to right. It also dputs all negative
2430+ * dentries except bindex
2431+ */
2432+ for (i = loop_start; i <= loop_end; i++) {
2433+ if (!unionfs_lower_dentry_idx(dentry, i))
2434+ continue;
2435+
2436+ if (i == bindex) {
2437+ new_bend = i;
2438+ if (new_bstart < 0)
2439+ new_bstart = i;
2440+ continue;
2441+ }
2442+
2443+ if (!unionfs_lower_dentry_idx(dentry, i)->d_inode) {
2444+ dput(unionfs_lower_dentry_idx(dentry, i));
2445+ unionfs_set_lower_dentry_idx(dentry, i, NULL);
2446+
2447+ unionfs_mntput(dentry, i);
2448+ unionfs_set_lower_mnt_idx(dentry, i, NULL);
2449+ } else {
2450+ if (new_bstart < 0)
2451+ new_bstart = i;
2452+ new_bend = i;
2453+ }
2454+ }
2455+
2456+ if (new_bstart < 0)
2457+ new_bstart = bindex;
2458+ if (new_bend < 0)
2459+ new_bend = bindex;
2460+ dbstart(dentry) = new_bstart;
2461+ dbend(dentry) = new_bend;
2462+
2463+}
2464+
2465+/* set lower inode ptr and update bstart & bend if necessary */
2466+static void __set_inode(struct dentry *upper, struct dentry *lower,
2467+ int bindex)
2468+{
2469+ unionfs_set_lower_inode_idx(upper->d_inode, bindex,
2470+ igrab(lower->d_inode));
2471+ if (likely(ibstart(upper->d_inode) > bindex))
2472+ ibstart(upper->d_inode) = bindex;
2473+ if (likely(ibend(upper->d_inode) < bindex))
2474+ ibend(upper->d_inode) = bindex;
2475+
2476+}
2477+
2478+/* set lower dentry ptr and update bstart & bend if necessary */
2479+static void __set_dentry(struct dentry *upper, struct dentry *lower,
2480+ int bindex)
2481+{
2482+ unionfs_set_lower_dentry_idx(upper, bindex, lower);
2483+ if (likely(dbstart(upper) > bindex))
2484+ dbstart(upper) = bindex;
2485+ if (likely(dbend(upper) < bindex))
2486+ dbend(upper) = bindex;
2487+}
2488+
2489+/*
2490+ * This function replicates the directory structure up-to given dentry
2491+ * in the bindex branch.
2492+ */
2493+struct dentry *create_parents(struct inode *dir, struct dentry *dentry,
2494+ const char *name, int bindex)
2495+{
2496+ int err;
2497+ struct dentry *child_dentry;
2498+ struct dentry *parent_dentry;
2499+ struct dentry *lower_parent_dentry = NULL;
2500+ struct dentry *lower_dentry = NULL;
2501+ const char *childname;
2502+ unsigned int childnamelen;
2503+ int nr_dentry;
2504+ int count = 0;
2505+ int old_bstart;
2506+ int old_bend;
2507+ struct dentry **path = NULL;
2508+ struct super_block *sb;
2509+
2510+ verify_locked(dentry);
2511+
2512+ err = is_robranch_super(dir->i_sb, bindex);
2513+ if (err) {
2514+ lower_dentry = ERR_PTR(err);
2515+ goto out;
2516+ }
2517+
2518+ old_bstart = dbstart(dentry);
2519+ old_bend = dbend(dentry);
2520+
2521+ lower_dentry = ERR_PTR(-ENOMEM);
2522+
2523+ /* There is no sense allocating any less than the minimum. */
2524+ nr_dentry = 1;
2525+ path = kmalloc(nr_dentry * sizeof(struct dentry *), GFP_KERNEL);
2526+ if (unlikely(!path))
2527+ goto out;
2528+
2529+ /* assume the negative dentry of unionfs as the parent dentry */
2530+ parent_dentry = dentry;
2531+
2532+ /*
2533+ * This loop finds the first parent that exists in the given branch.
2534+ * We start building the directory structure from there. At the end
2535+ * of the loop, the following should hold:
2536+ * - child_dentry is the first nonexistent child
2537+ * - parent_dentry is the first existent parent
2538+ * - path[0] is the = deepest child
2539+ * - path[count] is the first child to create
2540+ */
2541+ do {
2542+ child_dentry = parent_dentry;
2543+
2544+ /* find the parent directory dentry in unionfs */
2545+ parent_dentry = dget_parent(child_dentry);
2546+
2547+ /* find out the lower_parent_dentry in the given branch */
2548+ lower_parent_dentry =
2549+ unionfs_lower_dentry_idx(parent_dentry, bindex);
2550+
2551+ /* grow path table */
2552+ if (count == nr_dentry) {
2553+ void *p;
2554+
2555+ nr_dentry *= 2;
2556+ p = krealloc(path, nr_dentry * sizeof(struct dentry *),
2557+ GFP_KERNEL);
2558+ if (unlikely(!p)) {
2559+ lower_dentry = ERR_PTR(-ENOMEM);
2560+ goto out;
2561+ }
2562+ path = p;
2563+ }
2564+
2565+ /* store the child dentry */
2566+ path[count++] = child_dentry;
2567+ } while (!lower_parent_dentry);
2568+ count--;
2569+
2570+ sb = dentry->d_sb;
2571+
2572+ /*
2573+ * This code goes between the begin/end labels and basically
2574+ * emulates a while(child_dentry != dentry), only cleaner and
2575+ * shorter than what would be a much longer while loop.
2576+ */
2577+begin:
2578+ /* get lower parent dir in the current branch */
2579+ lower_parent_dentry = unionfs_lower_dentry_idx(parent_dentry, bindex);
2580+ dput(parent_dentry);
2581+
2582+ /* init the values to lookup */
2583+ childname = child_dentry->d_name.name;
2584+ childnamelen = child_dentry->d_name.len;
2585+
2586+ if (child_dentry != dentry) {
2587+ /* lookup child in the underlying file system */
2588+ lower_dentry = lookup_one_len(childname, lower_parent_dentry,
2589+ childnamelen);
2590+ if (IS_ERR(lower_dentry))
2591+ goto out;
2592+ } else {
2593+ /*
2594+ * Is the name a whiteout of the child name ? lookup the
2595+ * whiteout child in the underlying file system
2596+ */
2597+ lower_dentry = lookup_one_len(name, lower_parent_dentry,
2598+ strlen(name));
2599+ if (IS_ERR(lower_dentry))
2600+ goto out;
2601+
2602+ /* Replace the current dentry (if any) with the new one */
2603+ dput(unionfs_lower_dentry_idx(dentry, bindex));
2604+ unionfs_set_lower_dentry_idx(dentry, bindex,
2605+ lower_dentry);
2606+
2607+ __cleanup_dentry(dentry, bindex, old_bstart, old_bend);
2608+ goto out;
2609+ }
2610+
2611+ if (lower_dentry->d_inode) {
2612+ /*
2613+ * since this already exists we dput to avoid
2614+ * multiple references on the same dentry
2615+ */
2616+ dput(lower_dentry);
2617+ } else {
2618+ struct sioq_args args;
2619+
2620+ /* it's a negative dentry, create a new dir */
2621+ lower_parent_dentry = lock_parent(lower_dentry);
2622+
2623+ args.mkdir.parent = lower_parent_dentry->d_inode;
2624+ args.mkdir.dentry = lower_dentry;
2625+ args.mkdir.mode = child_dentry->d_inode->i_mode;
2626+
2627+ run_sioq(__unionfs_mkdir, &args);
2628+ err = args.err;
2629+
2630+ if (!err)
2631+ err = copyup_permissions(dir->i_sb, child_dentry,
2632+ lower_dentry);
2633+ unlock_dir(lower_parent_dentry);
2634+ if (err) {
2635+ dput(lower_dentry);
2636+ lower_dentry = ERR_PTR(err);
2637+ goto out;
2638+ }
2639+
2640+ }
2641+
2642+ __set_inode(child_dentry, lower_dentry, bindex);
2643+ __set_dentry(child_dentry, lower_dentry, bindex);
2644+ /*
2645+ * update times of this dentry, but also the parent, because if
2646+ * we changed, the parent may have changed too.
2647+ */
2648+ fsstack_copy_attr_times(parent_dentry->d_inode,
2649+ lower_parent_dentry->d_inode);
2650+ unionfs_copy_attr_times(child_dentry->d_inode);
2651+
2652+ parent_dentry = child_dentry;
2653+ child_dentry = path[--count];
2654+ goto begin;
2655+out:
2656+ /* cleanup any leftover locks from the do/while loop above */
2657+ if (IS_ERR(lower_dentry))
2658+ while (count)
2659+ dput(path[count--]);
2660+ kfree(path);
2661+ return lower_dentry;
2662+}
2663+
2664+/*
2665+ * Post-copyup helper to ensure we have valid mnts: set lower mnt of
2666+ * dentry+parents to the first parent node that has an mnt.
2667+ */
2668+void unionfs_postcopyup_setmnt(struct dentry *dentry)
2669+{
2670+ struct dentry *parent, *hasone;
2671+ int bindex = dbstart(dentry);
2672+
2673+ if (unionfs_lower_mnt_idx(dentry, bindex))
2674+ return;
2675+ hasone = dentry->d_parent;
2676+ /* this loop should stop at root dentry */
2677+ while (!unionfs_lower_mnt_idx(hasone, bindex))
2678+ hasone = hasone->d_parent;
2679+ parent = dentry;
2680+ while (!unionfs_lower_mnt_idx(parent, bindex)) {
2681+ unionfs_set_lower_mnt_idx(parent, bindex,
2682+ unionfs_mntget(hasone, bindex));
2683+ parent = parent->d_parent;
2684+ }
2685+}
2686+
2687+/*
2688+ * Post-copyup helper to release all non-directory source objects of a
2689+ * copied-up file. Regular files should have only one lower object.
2690+ */
2691+void unionfs_postcopyup_release(struct dentry *dentry)
2692+{
2693+ int bstart, bend;
2694+
2695+ BUG_ON(S_ISDIR(dentry->d_inode->i_mode));
2696+ bstart = dbstart(dentry);
2697+ bend = dbend(dentry);
2698+
2699+ path_put_lowers(dentry, bstart + 1, bend, false);
2700+ iput_lowers(dentry->d_inode, bstart + 1, bend, false);
2701+
2702+ dbend(dentry) = bstart;
2703+ ibend(dentry->d_inode) = ibstart(dentry->d_inode) = bstart;
2704+}
2705diff --git a/fs/unionfs/debug.c b/fs/unionfs/debug.c
2706new file mode 100644
2707index 0000000..db62d22
2708--- /dev/null
2709+++ b/fs/unionfs/debug.c
2710@@ -0,0 +1,533 @@
2711+/*
2712+ * Copyright (c) 2003-2008 Erez Zadok
2713+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
2714+ * Copyright (c) 2003-2008 Stony Brook University
2715+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
2716+ *
2717+ * This program is free software; you can redistribute it and/or modify
2718+ * it under the terms of the GNU General Public License version 2 as
2719+ * published by the Free Software Foundation.
2720+ */
2721+
2722+#include "union.h"
2723+
2724+/*
2725+ * Helper debugging functions for maintainers (and for users to report back
2726+ * useful information back to maintainers)
2727+ */
2728+
2729+/* it's always useful to know what part of the code called us */
2730+#define PRINT_CALLER(fname, fxn, line) \
2731+ do { \
2732+ if (!printed_caller) { \
2733+ pr_debug("PC:%s:%s:%d\n", (fname), (fxn), (line)); \
2734+ printed_caller = 1; \
2735+ } \
2736+ } while (0)
2737+
2738+/*
2739+ * __unionfs_check_{inode,dentry,file} perform exhaustive sanity checking on
2740+ * the fan-out of various Unionfs objects. We check that no lower objects
2741+ * exist outside the start/end branch range; that all objects within are
2742+ * non-NULL (with some allowed exceptions); that for every lower file
2743+ * there's a lower dentry+inode; that the start/end ranges match for all
2744+ * corresponding lower objects; that open files/symlinks have only one lower
2745+ * objects, but directories can have several; and more.
2746+ */
2747+void __unionfs_check_inode(const struct inode *inode,
2748+ const char *fname, const char *fxn, int line)
2749+{
2750+ int bindex;
2751+ int istart, iend;
2752+ struct inode *lower_inode;
2753+ struct super_block *sb;
2754+ int printed_caller = 0;
2755+ void *poison_ptr;
2756+
2757+ /* for inodes now */
2758+ BUG_ON(!inode);
2759+ sb = inode->i_sb;
2760+ istart = ibstart(inode);
2761+ iend = ibend(inode);
2762+ /* don't check inode if no lower branches */
2763+ if (istart < 0 && iend < 0)
2764+ return;
2765+ if (unlikely(istart > iend)) {
2766+ PRINT_CALLER(fname, fxn, line);
2767+ pr_debug(" Ci0: inode=%p istart/end=%d:%d\n",
2768+ inode, istart, iend);
2769+ }
2770+ if (unlikely((istart == -1 && iend != -1) ||
2771+ (istart != -1 && iend == -1))) {
2772+ PRINT_CALLER(fname, fxn, line);
2773+ pr_debug(" Ci1: inode=%p istart/end=%d:%d\n",
2774+ inode, istart, iend);
2775+ }
2776+ if (!S_ISDIR(inode->i_mode)) {
2777+ if (unlikely(iend != istart)) {
2778+ PRINT_CALLER(fname, fxn, line);
2779+ pr_debug(" Ci2: inode=%p istart=%d iend=%d\n",
2780+ inode, istart, iend);
2781+ }
2782+ }
2783+
2784+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
2785+ if (unlikely(!UNIONFS_I(inode))) {
2786+ PRINT_CALLER(fname, fxn, line);
2787+ pr_debug(" Ci3: no inode_info %p\n", inode);
2788+ return;
2789+ }
2790+ if (unlikely(!UNIONFS_I(inode)->lower_inodes)) {
2791+ PRINT_CALLER(fname, fxn, line);
2792+ pr_debug(" Ci4: no lower_inodes %p\n", inode);
2793+ return;
2794+ }
2795+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
2796+ if (lower_inode) {
2797+ memset(&poison_ptr, POISON_INUSE, sizeof(void *));
2798+ if (unlikely(bindex < istart || bindex > iend)) {
2799+ PRINT_CALLER(fname, fxn, line);
2800+ pr_debug(" Ci5: inode/linode=%p:%p bindex=%d "
2801+ "istart/end=%d:%d\n", inode,
2802+ lower_inode, bindex, istart, iend);
2803+ } else if (unlikely(lower_inode == poison_ptr)) {
2804+ /* freed inode! */
2805+ PRINT_CALLER(fname, fxn, line);
2806+ pr_debug(" Ci6: inode/linode=%p:%p bindex=%d "
2807+ "istart/end=%d:%d\n", inode,
2808+ lower_inode, bindex, istart, iend);
2809+ }
2810+ continue;
2811+ }
2812+ /* if we get here, then lower_inode == NULL */
2813+ if (bindex < istart || bindex > iend)
2814+ continue;
2815+ /*
2816+ * directories can have NULL lower inodes in b/t start/end,
2817+ * but NOT if at the start/end range.
2818+ */
2819+ if (unlikely(S_ISDIR(inode->i_mode) &&
2820+ bindex > istart && bindex < iend))
2821+ continue;
2822+ PRINT_CALLER(fname, fxn, line);
2823+ pr_debug(" Ci7: inode/linode=%p:%p "
2824+ "bindex=%d istart/end=%d:%d\n",
2825+ inode, lower_inode, bindex, istart, iend);
2826+ }
2827+}
2828+
2829+void __unionfs_check_dentry(const struct dentry *dentry,
2830+ const char *fname, const char *fxn, int line)
2831+{
2832+ int bindex;
2833+ int dstart, dend, istart, iend;
2834+ struct dentry *lower_dentry;
2835+ struct inode *inode, *lower_inode;
2836+ struct super_block *sb;
2837+ struct vfsmount *lower_mnt;
2838+ int printed_caller = 0;
2839+ void *poison_ptr;
2840+
2841+ BUG_ON(!dentry);
2842+ sb = dentry->d_sb;
2843+ inode = dentry->d_inode;
2844+ dstart = dbstart(dentry);
2845+ dend = dbend(dentry);
2846+ /* don't check dentry/mnt if no lower branches */
2847+ if (dstart < 0 && dend < 0)
2848+ goto check_inode;
2849+ BUG_ON(dstart > dend);
2850+
2851+ if (unlikely((dstart == -1 && dend != -1) ||
2852+ (dstart != -1 && dend == -1))) {
2853+ PRINT_CALLER(fname, fxn, line);
2854+ pr_debug(" CD0: dentry=%p dstart/end=%d:%d\n",
2855+ dentry, dstart, dend);
2856+ }
2857+ /*
2858+ * check for NULL dentries inside the start/end range, or
2859+ * non-NULL dentries outside the start/end range.
2860+ */
2861+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
2862+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
2863+ if (lower_dentry) {
2864+ if (unlikely(bindex < dstart || bindex > dend)) {
2865+ PRINT_CALLER(fname, fxn, line);
2866+ pr_debug(" CD1: dentry/lower=%p:%p(%p) "
2867+ "bindex=%d dstart/end=%d:%d\n",
2868+ dentry, lower_dentry,
2869+ (lower_dentry ? lower_dentry->d_inode :
2870+ (void *) -1L),
2871+ bindex, dstart, dend);
2872+ }
2873+ } else { /* lower_dentry == NULL */
2874+ if (bindex < dstart || bindex > dend)
2875+ continue;
2876+ /*
2877+ * Directories can have NULL lower inodes in b/t
2878+ * start/end, but NOT if at the start/end range.
2879+ * Ignore this rule, however, if this is a NULL
2880+ * dentry or a deleted dentry.
2881+ */
2882+ if (unlikely(!d_deleted((struct dentry *) dentry) &&
2883+ inode &&
2884+ !(inode && S_ISDIR(inode->i_mode) &&
2885+ bindex > dstart && bindex < dend))) {
2886+ PRINT_CALLER(fname, fxn, line);
2887+ pr_debug(" CD2: dentry/lower=%p:%p(%p) "
2888+ "bindex=%d dstart/end=%d:%d\n",
2889+ dentry, lower_dentry,
2890+ (lower_dentry ?
2891+ lower_dentry->d_inode :
2892+ (void *) -1L),
2893+ bindex, dstart, dend);
2894+ }
2895+ }
2896+ }
2897+
2898+ /* check for vfsmounts same as for dentries */
2899+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
2900+ lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
2901+ if (lower_mnt) {
2902+ if (unlikely(bindex < dstart || bindex > dend)) {
2903+ PRINT_CALLER(fname, fxn, line);
2904+ pr_debug(" CM0: dentry/lmnt=%p:%p bindex=%d "
2905+ "dstart/end=%d:%d\n", dentry,
2906+ lower_mnt, bindex, dstart, dend);
2907+ }
2908+ } else { /* lower_mnt == NULL */
2909+ if (bindex < dstart || bindex > dend)
2910+ continue;
2911+ /*
2912+ * Directories can have NULL lower inodes in b/t
2913+ * start/end, but NOT if at the start/end range.
2914+ * Ignore this rule, however, if this is a NULL
2915+ * dentry.
2916+ */
2917+ if (unlikely(inode &&
2918+ !(inode && S_ISDIR(inode->i_mode) &&
2919+ bindex > dstart && bindex < dend))) {
2920+ PRINT_CALLER(fname, fxn, line);
2921+ pr_debug(" CM1: dentry/lmnt=%p:%p "
2922+ "bindex=%d dstart/end=%d:%d\n",
2923+ dentry, lower_mnt, bindex,
2924+ dstart, dend);
2925+ }
2926+ }
2927+ }
2928+
2929+check_inode:
2930+ /* for inodes now */
2931+ if (!inode)
2932+ return;
2933+ istart = ibstart(inode);
2934+ iend = ibend(inode);
2935+ /* don't check inode if no lower branches */
2936+ if (istart < 0 && iend < 0)
2937+ return;
2938+ BUG_ON(istart > iend);
2939+ if (unlikely((istart == -1 && iend != -1) ||
2940+ (istart != -1 && iend == -1))) {
2941+ PRINT_CALLER(fname, fxn, line);
2942+ pr_debug(" CI0: dentry/inode=%p:%p istart/end=%d:%d\n",
2943+ dentry, inode, istart, iend);
2944+ }
2945+ if (unlikely(istart != dstart)) {
2946+ PRINT_CALLER(fname, fxn, line);
2947+ pr_debug(" CI1: dentry/inode=%p:%p istart=%d dstart=%d\n",
2948+ dentry, inode, istart, dstart);
2949+ }
2950+ if (unlikely(iend != dend)) {
2951+ PRINT_CALLER(fname, fxn, line);
2952+ pr_debug(" CI2: dentry/inode=%p:%p iend=%d dend=%d\n",
2953+ dentry, inode, iend, dend);
2954+ }
2955+
2956+ if (!S_ISDIR(inode->i_mode)) {
2957+ if (unlikely(dend != dstart)) {
2958+ PRINT_CALLER(fname, fxn, line);
2959+ pr_debug(" CI3: dentry/inode=%p:%p dstart=%d dend=%d\n",
2960+ dentry, inode, dstart, dend);
2961+ }
2962+ if (unlikely(iend != istart)) {
2963+ PRINT_CALLER(fname, fxn, line);
2964+ pr_debug(" CI4: dentry/inode=%p:%p istart=%d iend=%d\n",
2965+ dentry, inode, istart, iend);
2966+ }
2967+ }
2968+
2969+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
2970+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
2971+ if (lower_inode) {
2972+ memset(&poison_ptr, POISON_INUSE, sizeof(void *));
2973+ if (unlikely(bindex < istart || bindex > iend)) {
2974+ PRINT_CALLER(fname, fxn, line);
2975+ pr_debug(" CI5: dentry/linode=%p:%p bindex=%d "
2976+ "istart/end=%d:%d\n", dentry,
2977+ lower_inode, bindex, istart, iend);
2978+ } else if (unlikely(lower_inode == poison_ptr)) {
2979+ /* freed inode! */
2980+ PRINT_CALLER(fname, fxn, line);
2981+ pr_debug(" CI6: dentry/linode=%p:%p bindex=%d "
2982+ "istart/end=%d:%d\n", dentry,
2983+ lower_inode, bindex, istart, iend);
2984+ }
2985+ continue;
2986+ }
2987+ /* if we get here, then lower_inode == NULL */
2988+ if (bindex < istart || bindex > iend)
2989+ continue;
2990+ /*
2991+ * directories can have NULL lower inodes in b/t start/end,
2992+ * but NOT if at the start/end range.
2993+ */
2994+ if (unlikely(S_ISDIR(inode->i_mode) &&
2995+ bindex > istart && bindex < iend))
2996+ continue;
2997+ PRINT_CALLER(fname, fxn, line);
2998+ pr_debug(" CI7: dentry/linode=%p:%p "
2999+ "bindex=%d istart/end=%d:%d\n",
3000+ dentry, lower_inode, bindex, istart, iend);
3001+ }
3002+
3003+ /*
3004+ * If it's a directory, then intermediate objects b/t start/end can
3005+ * be NULL. But, check that all three are NULL: lower dentry, mnt,
3006+ * and inode.
3007+ */
3008+ if (dstart >= 0 && dend >= 0 && S_ISDIR(inode->i_mode))
3009+ for (bindex = dstart+1; bindex < dend; bindex++) {
3010+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
3011+ lower_dentry = unionfs_lower_dentry_idx(dentry,
3012+ bindex);
3013+ lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
3014+ if (unlikely(!((lower_inode && lower_dentry &&
3015+ lower_mnt) ||
3016+ (!lower_inode &&
3017+ !lower_dentry && !lower_mnt)))) {
3018+ PRINT_CALLER(fname, fxn, line);
3019+ pr_debug(" Cx: lmnt/ldentry/linode=%p:%p:%p "
3020+ "bindex=%d dstart/end=%d:%d\n",
3021+ lower_mnt, lower_dentry, lower_inode,
3022+ bindex, dstart, dend);
3023+ }
3024+ }
3025+ /* check if lower inode is newer than upper one (it shouldn't) */
3026+ if (unlikely(is_newer_lower(dentry) && !is_negative_lower(dentry))) {
3027+ PRINT_CALLER(fname, fxn, line);
3028+ for (bindex = ibstart(inode); bindex <= ibend(inode);
3029+ bindex++) {
3030+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
3031+ if (unlikely(!lower_inode))
3032+ continue;
3033+ pr_debug(" CI8: bindex=%d mtime/lmtime=%lu.%lu/%lu.%lu "
3034+ "ctime/lctime=%lu.%lu/%lu.%lu\n",
3035+ bindex,
3036+ inode->i_mtime.tv_sec,
3037+ inode->i_mtime.tv_nsec,
3038+ lower_inode->i_mtime.tv_sec,
3039+ lower_inode->i_mtime.tv_nsec,
3040+ inode->i_ctime.tv_sec,
3041+ inode->i_ctime.tv_nsec,
3042+ lower_inode->i_ctime.tv_sec,
3043+ lower_inode->i_ctime.tv_nsec);
3044+ }
3045+ }
3046+}
3047+
3048+void __unionfs_check_file(const struct file *file,
3049+ const char *fname, const char *fxn, int line)
3050+{
3051+ int bindex;
3052+ int dstart, dend, fstart, fend;
3053+ struct dentry *dentry;
3054+ struct file *lower_file;
3055+ struct inode *inode;
3056+ struct super_block *sb;
3057+ int printed_caller = 0;
3058+
3059+ BUG_ON(!file);
3060+ dentry = file->f_path.dentry;
3061+ sb = dentry->d_sb;
3062+ dstart = dbstart(dentry);
3063+ dend = dbend(dentry);
3064+ BUG_ON(dstart > dend);
3065+ fstart = fbstart(file);
3066+ fend = fbend(file);
3067+ BUG_ON(fstart > fend);
3068+
3069+ if (unlikely((fstart == -1 && fend != -1) ||
3070+ (fstart != -1 && fend == -1))) {
3071+ PRINT_CALLER(fname, fxn, line);
3072+ pr_debug(" CF0: file/dentry=%p:%p fstart/end=%d:%d\n",
3073+ file, dentry, fstart, fend);
3074+ }
3075+ if (unlikely(fstart != dstart)) {
3076+ PRINT_CALLER(fname, fxn, line);
3077+ pr_debug(" CF1: file/dentry=%p:%p fstart=%d dstart=%d\n",
3078+ file, dentry, fstart, dstart);
3079+ }
3080+ if (unlikely(fend != dend)) {
3081+ PRINT_CALLER(fname, fxn, line);
3082+ pr_debug(" CF2: file/dentry=%p:%p fend=%d dend=%d\n",
3083+ file, dentry, fend, dend);
3084+ }
3085+ inode = dentry->d_inode;
3086+ if (!S_ISDIR(inode->i_mode)) {
3087+ if (unlikely(fend != fstart)) {
3088+ PRINT_CALLER(fname, fxn, line);
3089+ pr_debug(" CF3: file/inode=%p:%p fstart=%d fend=%d\n",
3090+ file, inode, fstart, fend);
3091+ }
3092+ if (unlikely(dend != dstart)) {
3093+ PRINT_CALLER(fname, fxn, line);
3094+ pr_debug(" CF4: file/dentry=%p:%p dstart=%d dend=%d\n",
3095+ file, dentry, dstart, dend);
3096+ }
3097+ }
3098+
3099+ /*
3100+ * check for NULL dentries inside the start/end range, or
3101+ * non-NULL dentries outside the start/end range.
3102+ */
3103+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
3104+ lower_file = unionfs_lower_file_idx(file, bindex);
3105+ if (lower_file) {
3106+ if (unlikely(bindex < fstart || bindex > fend)) {
3107+ PRINT_CALLER(fname, fxn, line);
3108+ pr_debug(" CF5: file/lower=%p:%p bindex=%d "
3109+ "fstart/end=%d:%d\n", file,
3110+ lower_file, bindex, fstart, fend);
3111+ }
3112+ } else { /* lower_file == NULL */
3113+ if (bindex >= fstart && bindex <= fend) {
3114+ /*
3115+ * directories can have NULL lower inodes in
3116+ * b/t start/end, but NOT if at the
3117+ * start/end range.
3118+ */
3119+ if (unlikely(!(S_ISDIR(inode->i_mode) &&
3120+ bindex > fstart &&
3121+ bindex < fend))) {
3122+ PRINT_CALLER(fname, fxn, line);
3123+ pr_debug(" CF6: file/lower=%p:%p "
3124+ "bindex=%d fstart/end=%d:%d\n",
3125+ file, lower_file, bindex,
3126+ fstart, fend);
3127+ }
3128+ }
3129+ }
3130+ }
3131+
3132+ __unionfs_check_dentry(dentry, fname, fxn, line);
3133+}
3134+
3135+void __unionfs_check_nd(const struct nameidata *nd,
3136+ const char *fname, const char *fxn, int line)
3137+{
3138+ struct file *file;
3139+ int printed_caller = 0;
3140+
3141+ if (unlikely(!nd))
3142+ return;
3143+ if (nd->flags & LOOKUP_OPEN) {
3144+ file = nd->intent.open.file;
3145+ if (unlikely(file->f_path.dentry &&
3146+ strcmp(file->f_path.dentry->d_sb->s_type->name,
3147+ UNIONFS_NAME))) {
3148+ PRINT_CALLER(fname, fxn, line);
3149+ pr_debug(" CND1: lower_file of type %s\n",
3150+ file->f_path.dentry->d_sb->s_type->name);
3151+ BUG();
3152+ }
3153+ }
3154+}
3155+
3156+/* useful to track vfsmount leaks that could cause EBUSY on unmount */
3157+void __show_branch_counts(const struct super_block *sb,
3158+ const char *file, const char *fxn, int line)
3159+{
3160+ int i;
3161+ struct vfsmount *mnt;
3162+
3163+ pr_debug("BC:");
3164+ for (i = 0; i < sbmax(sb); i++) {
3165+ if (likely(sb->s_root))
3166+ mnt = UNIONFS_D(sb->s_root)->lower_paths[i].mnt;
3167+ else
3168+ mnt = NULL;
3169+ printk(KERN_CONT "%d:",
3170+ (mnt ? atomic_read(&mnt->mnt_count) : -99));
3171+ }
3172+ printk(KERN_CONT "%s:%s:%d\n", file, fxn, line);
3173+}
3174+
3175+void __show_inode_times(const struct inode *inode,
3176+ const char *file, const char *fxn, int line)
3177+{
3178+ struct inode *lower_inode;
3179+ int bindex;
3180+
3181+ for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) {
3182+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
3183+ if (unlikely(!lower_inode))
3184+ continue;
3185+ pr_debug("IT(%lu:%d): %s:%s:%d "
3186+ "um=%lu/%lu lm=%lu/%lu uc=%lu/%lu lc=%lu/%lu\n",
3187+ inode->i_ino, bindex,
3188+ file, fxn, line,
3189+ inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
3190+ lower_inode->i_mtime.tv_sec,
3191+ lower_inode->i_mtime.tv_nsec,
3192+ inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
3193+ lower_inode->i_ctime.tv_sec,
3194+ lower_inode->i_ctime.tv_nsec);
3195+ }
3196+}
3197+
3198+void __show_dinode_times(const struct dentry *dentry,
3199+ const char *file, const char *fxn, int line)
3200+{
3201+ struct inode *inode = dentry->d_inode;
3202+ struct inode *lower_inode;
3203+ int bindex;
3204+
3205+ for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) {
3206+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
3207+ if (!lower_inode)
3208+ continue;
3209+ pr_debug("DT(%s:%lu:%d): %s:%s:%d "
3210+ "um=%lu/%lu lm=%lu/%lu uc=%lu/%lu lc=%lu/%lu\n",
3211+ dentry->d_name.name, inode->i_ino, bindex,
3212+ file, fxn, line,
3213+ inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
3214+ lower_inode->i_mtime.tv_sec,
3215+ lower_inode->i_mtime.tv_nsec,
3216+ inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
3217+ lower_inode->i_ctime.tv_sec,
3218+ lower_inode->i_ctime.tv_nsec);
3219+ }
3220+}
3221+
3222+void __show_inode_counts(const struct inode *inode,
3223+ const char *file, const char *fxn, int line)
3224+{
3225+ struct inode *lower_inode;
3226+ int bindex;
3227+
3228+ if (unlikely(!inode)) {
3229+ pr_debug("SiC: Null inode\n");
3230+ return;
3231+ }
3232+ for (bindex = sbstart(inode->i_sb); bindex <= sbend(inode->i_sb);
3233+ bindex++) {
3234+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
3235+ if (unlikely(!lower_inode))
3236+ continue;
3237+ pr_debug("SIC(%lu:%d:%d): lc=%d %s:%s:%d\n",
3238+ inode->i_ino, bindex,
3239+ atomic_read(&(inode)->i_count),
3240+ atomic_read(&(lower_inode)->i_count),
3241+ file, fxn, line);
3242+ }
3243+}
3244diff --git a/fs/unionfs/dentry.c b/fs/unionfs/dentry.c
3245new file mode 100644
3246index 0000000..7f0c7f7
3247--- /dev/null
3248+++ b/fs/unionfs/dentry.c
3249@@ -0,0 +1,570 @@
3250+/*
3251+ * Copyright (c) 2003-2008 Erez Zadok
3252+ * Copyright (c) 2003-2006 Charles P. Wright
3253+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
3254+ * Copyright (c) 2005-2006 Junjiro Okajima
3255+ * Copyright (c) 2005 Arun M. Krishnakumar
3256+ * Copyright (c) 2004-2006 David P. Quigley
3257+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
3258+ * Copyright (c) 2003 Puja Gupta
3259+ * Copyright (c) 2003 Harikesavan Krishnan
3260+ * Copyright (c) 2003-2008 Stony Brook University
3261+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
3262+ *
3263+ * This program is free software; you can redistribute it and/or modify
3264+ * it under the terms of the GNU General Public License version 2 as
3265+ * published by the Free Software Foundation.
3266+ */
3267+
3268+#include "union.h"
3269+
3270+bool is_negative_lower(const struct dentry *dentry)
3271+{
3272+ int bindex;
3273+ struct dentry *lower_dentry;
3274+
3275+ BUG_ON(!dentry);
3276+ /* cache coherency: check if file was deleted on lower branch */
3277+ if (dbstart(dentry) < 0)
3278+ return true;
3279+ for (bindex = dbstart(dentry); bindex <= dbend(dentry); bindex++) {
3280+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
3281+ /* unhashed (i.e., unlinked) lower dentries don't count */
3282+ if (lower_dentry && lower_dentry->d_inode &&
3283+ !d_deleted(lower_dentry) &&
3284+ !(lower_dentry->d_flags & DCACHE_NFSFS_RENAMED))
3285+ return false;
3286+ }
3287+ return true;
3288+}
3289+
3290+static inline void __dput_lowers(struct dentry *dentry, int start, int end)
3291+{
3292+ struct dentry *lower_dentry;
3293+ int bindex;
3294+
3295+ if (start < 0)
3296+ return;
3297+ for (bindex = start; bindex <= end; bindex++) {
3298+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
3299+ if (!lower_dentry)
3300+ continue;
3301+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
3302+ dput(lower_dentry);
3303+ }
3304+}
3305+
3306+/*
3307+ * Revalidate a single dentry.
3308+ * Assume that dentry's info node is locked.
3309+ * Assume that parent(s) are all valid already, but
3310+ * the child may not yet be valid.
3311+ * Returns true if valid, false otherwise.
3312+ */
3313+static bool __unionfs_d_revalidate_one(struct dentry *dentry,
3314+ struct nameidata *nd)
3315+{
3316+ bool valid = true; /* default is valid */
3317+ struct dentry *lower_dentry;
3318+ int bindex, bstart, bend;
3319+ int sbgen, dgen;
3320+ int positive = 0;
3321+ int interpose_flag;
3322+ struct nameidata lowernd; /* TODO: be gentler to the stack */
3323+
3324+ if (nd)
3325+ memcpy(&lowernd, nd, sizeof(struct nameidata));
3326+ else
3327+ memset(&lowernd, 0, sizeof(struct nameidata));
3328+
3329+ verify_locked(dentry);
3330+ verify_locked(dentry->d_parent);
3331+
3332+ sbgen = atomic_read(&UNIONFS_SB(dentry->d_sb)->generation);
3333+ /* if the dentry is unhashed, do NOT revalidate */
3334+ if (d_deleted(dentry))
3335+ goto out;
3336+
3337+ BUG_ON(dbstart(dentry) == -1);
3338+ if (dentry->d_inode)
3339+ positive = 1;
3340+ dgen = atomic_read(&UNIONFS_D(dentry)->generation);
3341+ /*
3342+ * If we are working on an unconnected dentry, then there is no
3343+ * revalidation to be done, because this file does not exist within
3344+ * the namespace, and Unionfs operates on the namespace, not data.
3345+ */
3346+ if (unlikely(sbgen != dgen)) {
3347+ struct dentry *result;
3348+ int pdgen;
3349+
3350+ /* The root entry should always be valid */
3351+ BUG_ON(IS_ROOT(dentry));
3352+
3353+ /* We can't work correctly if our parent isn't valid. */
3354+ pdgen = atomic_read(&UNIONFS_D(dentry->d_parent)->generation);
3355+ BUG_ON(pdgen != sbgen); /* should never happen here */
3356+
3357+ /* Free the pointers for our inodes and this dentry. */
3358+ bstart = dbstart(dentry);
3359+ bend = dbend(dentry);
3360+
3361+ /*
3362+ * mntput unhashed lower dentries, because those files got
3363+ * deleted or rmdir'ed.
3364+ */
3365+ for (bindex = bstart; bindex <= bend; bindex++) {
3366+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
3367+ if (!lower_dentry)
3368+ continue;
3369+ if (!d_deleted(lower_dentry) &&
3370+ !(lower_dentry->d_flags & DCACHE_NFSFS_RENAMED))
3371+ continue;
3372+ unionfs_mntput(dentry, bindex);
3373+ }
3374+
3375+ __dput_lowers(dentry, bstart, bend);
3376+ dbstart(dentry) = dbend(dentry) = -1;
3377+
3378+ interpose_flag = INTERPOSE_REVAL_NEG;
3379+ if (positive) {
3380+ interpose_flag = INTERPOSE_REVAL;
3381+ iput_lowers_all(dentry->d_inode, true);
3382+ }
3383+
3384+ if (realloc_dentry_private_data(dentry) != 0) {
3385+ valid = false;
3386+ goto out;
3387+ }
3388+
3389+ result = unionfs_lookup_full(dentry, &lowernd, interpose_flag);
3390+ if (result) {
3391+ if (IS_ERR(result)) {
3392+ valid = false;
3393+ goto out;
3394+ }
3395+ /*
3396+ * current unionfs_lookup_backend() doesn't return
3397+ * a valid dentry
3398+ */
3399+ dput(dentry);
3400+ dentry = result;
3401+ }
3402+
3403+ if (unlikely(positive && is_negative_lower(dentry))) {
3404+ make_bad_inode(dentry->d_inode);
3405+ d_drop(dentry);
3406+ valid = false;
3407+ goto out;
3408+ }
3409+ goto out;
3410+ }
3411+
3412+ /* The revalidation must occur across all branches */
3413+ bstart = dbstart(dentry);
3414+ bend = dbend(dentry);
3415+ BUG_ON(bstart == -1);
3416+ for (bindex = bstart; bindex <= bend; bindex++) {
3417+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
3418+ if (!lower_dentry || !lower_dentry->d_op
3419+ || !lower_dentry->d_op->d_revalidate)
3420+ continue;
3421+ /*
3422+ * Don't pass nameidata to lower file system, because we
3423+ * don't want an arbitrary lower file being opened or
3424+ * returned to us: it may be useless to us because of the
3425+ * fanout nature of unionfs (cf. file/directory open-file
3426+ * invariants). We will open lower files as and when needed
3427+ * later on.
3428+ */
3429+ if (!lower_dentry->d_op->d_revalidate(lower_dentry, NULL))
3430+ valid = false;
3431+ }
3432+
3433+ if (!dentry->d_inode ||
3434+ ibstart(dentry->d_inode) < 0 ||
3435+ ibend(dentry->d_inode) < 0) {
3436+ valid = false;
3437+ goto out;
3438+ }
3439+
3440+ if (valid) {
3441+ /*
3442+ * If we get here, and we copy the meta-data from the lower
3443+ * inode to our inode, then it is vital that we have already
3444+ * purged all unionfs-level file data. We do that in the
3445+ * caller (__unionfs_d_revalidate_chain) by calling
3446+ * purge_inode_data.
3447+ */
3448+ unionfs_copy_attr_all(dentry->d_inode,
3449+ unionfs_lower_inode(dentry->d_inode));
3450+ fsstack_copy_inode_size(dentry->d_inode,
3451+ unionfs_lower_inode(dentry->d_inode));
3452+ }
3453+
3454+out:
3455+ if (valid)
3456+ atomic_set(&UNIONFS_D(dentry)->generation, sbgen);
3457+
3458+ return valid;
3459+}
3460+
3461+/*
3462+ * Determine if the lower inode objects have changed from below the unionfs
3463+ * inode. Return true if changed, false otherwise.
3464+ *
3465+ * We check if the mtime or ctime have changed. However, the inode times
3466+ * can be changed by anyone without much protection, including
3467+ * asynchronously. This can sometimes cause unionfs to find that the lower
3468+ * file system doesn't change its inode times quick enough, resulting in a
3469+ * false positive indication (which is harmless, it just makes unionfs do
3470+ * extra work in re-validating the objects). To minimize the chances of
3471+ * these situations, we still consider such small time changes valid, but we
3472+ * don't print debugging messages unless the time changes are greater than
3473+ * UNIONFS_MIN_CC_TIME (which defaults to 3 seconds, as with NFS's acregmin)
3474+ * because significant changes are more likely due to users manually
3475+ * touching lower files.
3476+ */
3477+bool is_newer_lower(const struct dentry *dentry)
3478+{
3479+ int bindex;
3480+ struct inode *inode;
3481+ struct inode *lower_inode;
3482+
3483+ /* ignore if we're called on semi-initialized dentries/inodes */
3484+ if (!dentry || !UNIONFS_D(dentry))
3485+ return false;
3486+ inode = dentry->d_inode;
3487+ if (!inode || !UNIONFS_I(inode)->lower_inodes ||
3488+ ibstart(inode) < 0 || ibend(inode) < 0)
3489+ return false;
3490+
3491+ for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) {
3492+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
3493+ if (!lower_inode)
3494+ continue;
3495+
3496+ /* check if mtime/ctime have changed */
3497+ if (unlikely(timespec_compare(&inode->i_mtime,
3498+ &lower_inode->i_mtime) < 0)) {
3499+ if ((lower_inode->i_mtime.tv_sec -
3500+ inode->i_mtime.tv_sec) > UNIONFS_MIN_CC_TIME) {
3501+ pr_info("unionfs: new lower inode mtime "
3502+ "(bindex=%d, name=%s)\n", bindex,
3503+ dentry->d_name.name);
3504+ show_dinode_times(dentry);
3505+ }
3506+ return true;
3507+ }
3508+ if (unlikely(timespec_compare(&inode->i_ctime,
3509+ &lower_inode->i_ctime) < 0)) {
3510+ if ((lower_inode->i_ctime.tv_sec -
3511+ inode->i_ctime.tv_sec) > UNIONFS_MIN_CC_TIME) {
3512+ pr_info("unionfs: new lower inode ctime "
3513+ "(bindex=%d, name=%s)\n", bindex,
3514+ dentry->d_name.name);
3515+ show_dinode_times(dentry);
3516+ }
3517+ return true;
3518+ }
3519+ }
3520+
3521+ /*
3522+ * Last check: if this is a positive dentry, but somehow all lower
3523+ * dentries are negative or unhashed, then this dentry needs to be
3524+ * revalidated, because someone probably deleted the objects from
3525+ * the lower branches directly.
3526+ */
3527+ if (is_negative_lower(dentry))
3528+ return true;
3529+
3530+ return false; /* default: lower is not newer */
3531+}
3532+
3533+/*
3534+ * Purge and invalidate as many data pages of a unionfs inode. This is
3535+ * called when the lower inode has changed, and we want to force processes
3536+ * to re-get the new data.
3537+ */
3538+static inline void purge_inode_data(struct inode *inode)
3539+{
3540+ /* remove all non-private mappings */
3541+ unmap_mapping_range(inode->i_mapping, 0, 0, 0);
3542+ /* invalidate as many pages as possible */
3543+ invalidate_mapping_pages(inode->i_mapping, 0, -1);
3544+ /*
3545+ * Don't try to truncate_inode_pages here, because this could lead
3546+ * to a deadlock between some of address_space ops and dentry
3547+ * revalidation: the address space op is invoked with a lock on our
3548+ * own page, and truncate_inode_pages will block on locked pages.
3549+ */
3550+}
3551+
3552+/*
3553+ * Revalidate a single file/symlink/special dentry. Assume that info nodes
3554+ * of the dentry and its parent are locked. Assume that parent(s) are all
3555+ * valid already, but the child may not yet be valid. Returns true if
3556+ * valid, false otherwise.
3557+ */
3558+bool __unionfs_d_revalidate_one_locked(struct dentry *dentry,
3559+ struct nameidata *nd,
3560+ bool willwrite)
3561+{
3562+ bool valid = false; /* default is invalid */
3563+ int sbgen, dgen, bindex;
3564+
3565+ verify_locked(dentry);
3566+ verify_locked(dentry->d_parent);
3567+
3568+ sbgen = atomic_read(&UNIONFS_SB(dentry->d_sb)->generation);
3569+ dgen = atomic_read(&UNIONFS_D(dentry)->generation);
3570+
3571+ if (unlikely(is_newer_lower(dentry))) {
3572+ /* root dentry special case as aforementioned */
3573+ if (IS_ROOT(dentry)) {
3574+ unionfs_copy_attr_times(dentry->d_inode);
3575+ } else {
3576+ /*
3577+ * reset generation number to zero, guaranteed to be
3578+ * "old"
3579+ */
3580+ dgen = 0;
3581+ atomic_set(&UNIONFS_D(dentry)->generation, dgen);
3582+ }
3583+ if (!willwrite)
3584+ purge_inode_data(dentry->d_inode);
3585+ }
3586+ valid = __unionfs_d_revalidate_one(dentry, nd);
3587+
3588+ /*
3589+ * If __unionfs_d_revalidate_one() succeeded above, then it will
3590+ * have incremented the refcnt of the mnt's, but also the branch
3591+ * indices of the dentry will have been updated (to take into
3592+ * account any branch insertions/deletion. So the current
3593+ * dbstart/dbend match the current, and new, indices of the mnts
3594+ * which __unionfs_d_revalidate_one has incremented. Note: the "if"
3595+ * test below does not depend on whether chain_len was 0 or greater.
3596+ */
3597+ if (!valid || sbgen == dgen)
3598+ goto out;
3599+ for (bindex = dbstart(dentry); bindex <= dbend(dentry); bindex++)
3600+ unionfs_mntput(dentry, bindex);
3601+out:
3602+ return valid;
3603+}
3604+
3605+/*
3606+ * Revalidate a parent chain of dentries, then the actual node.
3607+ * Assumes that dentry is locked, but will lock all parents if/when needed.
3608+ *
3609+ * If 'willwrite' is true, and the lower inode times are not in sync, then
3610+ * *don't* purge_inode_data, as it could deadlock if ->write calls us and we
3611+ * try to truncate a locked page. Besides, if unionfs is about to write
3612+ * data to a file, then there's the data unionfs is about to write is more
3613+ * authoritative than what's below, therefore we can safely overwrite the
3614+ * lower inode times and data.
3615+ */
3616+bool __unionfs_d_revalidate_chain(struct dentry *dentry, struct nameidata *nd,
3617+ bool willwrite)
3618+{
3619+ bool valid = false; /* default is invalid */
3620+ struct dentry **chain = NULL; /* chain of dentries to reval */
3621+ int chain_len = 0;
3622+ struct dentry *dtmp;
3623+ int sbgen, dgen, i;
3624+ int saved_bstart, saved_bend, bindex;
3625+
3626+ /* find length of chain needed to revalidate */
3627+ /* XXX: should I grab some global (dcache?) lock? */
3628+ chain_len = 0;
3629+ sbgen = atomic_read(&UNIONFS_SB(dentry->d_sb)->generation);
3630+ dtmp = dentry->d_parent;
3631+ verify_locked(dentry);
3632+ if (dentry != dtmp)
3633+ unionfs_lock_dentry(dtmp, UNIONFS_DMUTEX_REVAL_PARENT);
3634+ dgen = atomic_read(&UNIONFS_D(dtmp)->generation);
3635+ /* XXX: should we check if is_newer_lower all the way up? */
3636+ if (unlikely(is_newer_lower(dtmp))) {
3637+ /*
3638+ * Special case: the root dentry's generation number must
3639+ * always be valid, but its lower inode times don't have to
3640+ * be, so sync up the times only.
3641+ */
3642+ if (IS_ROOT(dtmp)) {
3643+ unionfs_copy_attr_times(dtmp->d_inode);
3644+ } else {
3645+ /*
3646+ * reset generation number to zero, guaranteed to be
3647+ * "old"
3648+ */
3649+ dgen = 0;
3650+ atomic_set(&UNIONFS_D(dtmp)->generation, dgen);
3651+ }
3652+ purge_inode_data(dtmp->d_inode);
3653+ }
3654+ if (dentry != dtmp)
3655+ unionfs_unlock_dentry(dtmp);
3656+ while (sbgen != dgen) {
3657+ /* The root entry should always be valid */
3658+ BUG_ON(IS_ROOT(dtmp));
3659+ chain_len++;
3660+ dtmp = dtmp->d_parent;
3661+ dgen = atomic_read(&UNIONFS_D(dtmp)->generation);
3662+ }
3663+ if (chain_len == 0)
3664+ goto out_this; /* shortcut if parents are OK */
3665+
3666+ /*
3667+ * Allocate array of dentries to reval. We could use linked lists,
3668+ * but the number of entries we need to alloc here is often small,
3669+ * and short lived, so locality will be better.
3670+ */
3671+ chain = kzalloc(chain_len * sizeof(struct dentry *), GFP_KERNEL);
3672+ if (unlikely(!chain)) {
3673+ printk(KERN_CRIT "unionfs: no more memory in %s\n",
3674+ __func__);
3675+ goto out;
3676+ }
3677+
3678+ /* grab all dentries in chain, in child to parent order */
3679+ dtmp = dentry;
3680+ for (i = chain_len-1; i >= 0; i--)
3681+ dtmp = chain[i] = dget_parent(dtmp);
3682+
3683+ /*
3684+ * call __unionfs_d_revalidate_one() on each dentry, but in parent
3685+ * to child order.
3686+ */
3687+ for (i = 0; i < chain_len; i++) {
3688+ unionfs_lock_dentry(chain[i], UNIONFS_DMUTEX_REVAL_CHILD);
3689+ if (chain[i] != chain[i]->d_parent)
3690+ unionfs_lock_dentry(chain[i]->d_parent,
3691+ UNIONFS_DMUTEX_REVAL_PARENT);
3692+ saved_bstart = dbstart(chain[i]);
3693+ saved_bend = dbend(chain[i]);
3694+ sbgen = atomic_read(&UNIONFS_SB(dentry->d_sb)->generation);
3695+ dgen = atomic_read(&UNIONFS_D(chain[i])->generation);
3696+
3697+ valid = __unionfs_d_revalidate_one(chain[i], nd);
3698+ /* XXX: is this the correct mntput condition?! */
3699+ if (valid && chain_len > 0 &&
3700+ sbgen != dgen && chain[i]->d_inode &&
3701+ S_ISDIR(chain[i]->d_inode->i_mode)) {
3702+ for (bindex = saved_bstart; bindex <= saved_bend;
3703+ bindex++)
3704+ unionfs_mntput(chain[i], bindex);
3705+ }
3706+ if (chain[i] != chain[i]->d_parent)
3707+ unionfs_unlock_dentry(chain[i]->d_parent);
3708+ unionfs_unlock_dentry(chain[i]);
3709+
3710+ if (unlikely(!valid))
3711+ goto out_free;
3712+ }
3713+
3714+
3715+out_this:
3716+ /* finally, lock this dentry and revalidate it */
3717+ verify_locked(dentry); /* verify child is locked */
3718+ if (dentry != dentry->d_parent)
3719+ unionfs_lock_dentry(dentry->d_parent,
3720+ UNIONFS_DMUTEX_REVAL_PARENT);
3721+ valid = __unionfs_d_revalidate_one_locked(dentry, nd, willwrite);
3722+ if (dentry != dentry->d_parent)
3723+ unionfs_unlock_dentry(dentry->d_parent);
3724+
3725+out_free:
3726+ /* unlock/dput all dentries in chain and return status */
3727+ if (chain_len > 0) {
3728+ for (i = 0; i < chain_len; i++)
3729+ dput(chain[i]);
3730+ kfree(chain);
3731+ }
3732+out:
3733+ return valid;
3734+}
3735+
3736+static int unionfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
3737+{
3738+ int err;
3739+
3740+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
3741+
3742+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
3743+ err = __unionfs_d_revalidate_chain(dentry, nd, false);
3744+ if (likely(err > 0)) { /* true==1: dentry is valid */
3745+ unionfs_postcopyup_setmnt(dentry);
3746+ unionfs_check_dentry(dentry);
3747+ unionfs_check_nd(nd);
3748+ }
3749+ unionfs_unlock_dentry(dentry);
3750+
3751+ unionfs_read_unlock(dentry->d_sb);
3752+
3753+ return err;
3754+}
3755+
3756+static void unionfs_d_release(struct dentry *dentry)
3757+{
3758+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
3759+ if (unlikely(!UNIONFS_D(dentry)))
3760+ goto out; /* skip if no lower branches */
3761+ /* must lock our branch configuration here */
3762+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
3763+
3764+ unionfs_check_dentry(dentry);
3765+ /* this could be a negative dentry, so check first */
3766+ if (dbstart(dentry) < 0) {
3767+ unionfs_unlock_dentry(dentry);
3768+ goto out; /* due to a (normal) failed lookup */
3769+ }
3770+
3771+ /* Release all the lower dentries */
3772+ path_put_lowers_all(dentry, true);
3773+
3774+ unionfs_unlock_dentry(dentry);
3775+
3776+out:
3777+ free_dentry_private_data(dentry);
3778+ unionfs_read_unlock(dentry->d_sb);
3779+ return;
3780+}
3781+
3782+/*
3783+ * Called when we're removing the last reference to our dentry. So we
3784+ * should drop all lower references too.
3785+ */
3786+static void unionfs_d_iput(struct dentry *dentry, struct inode *inode)
3787+{
3788+ int rc;
3789+
3790+ BUG_ON(!dentry);
3791+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
3792+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
3793+
3794+ if (!UNIONFS_D(dentry) || dbstart(dentry) < 0)
3795+ goto drop_lower_inodes;
3796+ path_put_lowers_all(dentry, false);
3797+
3798+drop_lower_inodes:
3799+ rc = atomic_read(&inode->i_count);
3800+ if (rc == 1 && inode->i_nlink == 1 && ibstart(inode) >= 0) {
3801+ /* see Documentation/filesystems/unionfs/issues.txt */
3802+ lockdep_off();
3803+ iput(unionfs_lower_inode(inode));
3804+ lockdep_on();
3805+ unionfs_set_lower_inode(inode, NULL);
3806+ /* XXX: may need to set start/end to -1? */
3807+ }
3808+
3809+ iput(inode);
3810+
3811+ unionfs_unlock_dentry(dentry);
3812+ unionfs_read_unlock(dentry->d_sb);
3813+}
3814+
3815+struct dentry_operations unionfs_dops = {
3816+ .d_revalidate = unionfs_d_revalidate,
3817+ .d_release = unionfs_d_release,
3818+ .d_iput = unionfs_d_iput,
3819+};
3820diff --git a/fs/unionfs/dirfops.c b/fs/unionfs/dirfops.c
3821new file mode 100644
3822index 0000000..14ca7d3
3823--- /dev/null
3824+++ b/fs/unionfs/dirfops.c
3825@@ -0,0 +1,292 @@
3826+/*
3827+ * Copyright (c) 2003-2008 Erez Zadok
3828+ * Copyright (c) 2003-2006 Charles P. Wright
3829+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
3830+ * Copyright (c) 2005-2006 Junjiro Okajima
3831+ * Copyright (c) 2005 Arun M. Krishnakumar
3832+ * Copyright (c) 2004-2006 David P. Quigley
3833+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
3834+ * Copyright (c) 2003 Puja Gupta
3835+ * Copyright (c) 2003 Harikesavan Krishnan
3836+ * Copyright (c) 2003-2008 Stony Brook University
3837+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
3838+ *
3839+ * This program is free software; you can redistribute it and/or modify
3840+ * it under the terms of the GNU General Public License version 2 as
3841+ * published by the Free Software Foundation.
3842+ */
3843+
3844+#include "union.h"
3845+
3846+/* Make sure our rdstate is playing by the rules. */
3847+static void verify_rdstate_offset(struct unionfs_dir_state *rdstate)
3848+{
3849+ BUG_ON(rdstate->offset >= DIREOF);
3850+ BUG_ON(rdstate->cookie >= MAXRDCOOKIE);
3851+}
3852+
3853+struct unionfs_getdents_callback {
3854+ struct unionfs_dir_state *rdstate;
3855+ void *dirent;
3856+ int entries_written;
3857+ int filldir_called;
3858+ int filldir_error;
3859+ filldir_t filldir;
3860+ struct super_block *sb;
3861+};
3862+
3863+/* based on generic filldir in fs/readir.c */
3864+static int unionfs_filldir(void *dirent, const char *oname, int namelen,
3865+ loff_t offset, u64 ino, unsigned int d_type)
3866+{
3867+ struct unionfs_getdents_callback *buf = dirent;
3868+ struct filldir_node *found = NULL;
3869+ int err = 0;
3870+ int is_whiteout;
3871+ char *name = (char *) oname;
3872+
3873+ buf->filldir_called++;
3874+
3875+ is_whiteout = is_whiteout_name(&name, &namelen);
3876+
3877+ found = find_filldir_node(buf->rdstate, name, namelen, is_whiteout);
3878+
3879+ if (found) {
3880+ /*
3881+ * If we had non-whiteout entry in dir cache, then mark it
3882+ * as a whiteout and but leave it in the dir cache.
3883+ */
3884+ if (is_whiteout && !found->whiteout)
3885+ found->whiteout = is_whiteout;
3886+ goto out;
3887+ }
3888+
3889+ /* if 'name' isn't a whiteout, filldir it. */
3890+ if (!is_whiteout) {
3891+ off_t pos = rdstate2offset(buf->rdstate);
3892+ u64 unionfs_ino = ino;
3893+
3894+ err = buf->filldir(buf->dirent, name, namelen, pos,
3895+ unionfs_ino, d_type);
3896+ buf->rdstate->offset++;
3897+ verify_rdstate_offset(buf->rdstate);
3898+ }
3899+ /*
3900+ * If we did fill it, stuff it in our hash, otherwise return an
3901+ * error.
3902+ */
3903+ if (err) {
3904+ buf->filldir_error = err;
3905+ goto out;
3906+ }
3907+ buf->entries_written++;
3908+ err = add_filldir_node(buf->rdstate, name, namelen,
3909+ buf->rdstate->bindex, is_whiteout);
3910+ if (err)
3911+ buf->filldir_error = err;
3912+
3913+out:
3914+ return err;
3915+}
3916+
3917+static int unionfs_readdir(struct file *file, void *dirent, filldir_t filldir)
3918+{
3919+ int err = 0;
3920+ struct file *lower_file = NULL;
3921+ struct dentry *dentry = file->f_path.dentry;
3922+ struct inode *inode = NULL;
3923+ struct unionfs_getdents_callback buf;
3924+ struct unionfs_dir_state *uds;
3925+ int bend;
3926+ loff_t offset;
3927+
3928+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
3929+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
3930+
3931+ err = unionfs_file_revalidate(file, false);
3932+ if (unlikely(err))
3933+ goto out;
3934+
3935+ inode = dentry->d_inode;
3936+
3937+ uds = UNIONFS_F(file)->rdstate;
3938+ if (!uds) {
3939+ if (file->f_pos == DIREOF) {
3940+ goto out;
3941+ } else if (file->f_pos > 0) {
3942+ uds = find_rdstate(inode, file->f_pos);
3943+ if (unlikely(!uds)) {
3944+ err = -ESTALE;
3945+ goto out;
3946+ }
3947+ UNIONFS_F(file)->rdstate = uds;
3948+ } else {
3949+ init_rdstate(file);
3950+ uds = UNIONFS_F(file)->rdstate;
3951+ }
3952+ }
3953+ bend = fbend(file);
3954+
3955+ while (uds->bindex <= bend) {
3956+ lower_file = unionfs_lower_file_idx(file, uds->bindex);
3957+ if (!lower_file) {
3958+ uds->bindex++;
3959+ uds->dirpos = 0;
3960+ continue;
3961+ }
3962+
3963+ /* prepare callback buffer */
3964+ buf.filldir_called = 0;
3965+ buf.filldir_error = 0;
3966+ buf.entries_written = 0;
3967+ buf.dirent = dirent;
3968+ buf.filldir = filldir;
3969+ buf.rdstate = uds;
3970+ buf.sb = inode->i_sb;
3971+
3972+ /* Read starting from where we last left off. */
3973+ offset = vfs_llseek(lower_file, uds->dirpos, SEEK_SET);
3974+ if (offset < 0) {
3975+ err = offset;
3976+ goto out;
3977+ }
3978+ err = vfs_readdir(lower_file, unionfs_filldir, &buf);
3979+
3980+ /* Save the position for when we continue. */
3981+ offset = vfs_llseek(lower_file, 0, SEEK_CUR);
3982+ if (offset < 0) {
3983+ err = offset;
3984+ goto out;
3985+ }
3986+ uds->dirpos = offset;
3987+
3988+ /* Copy the atime. */
3989+ fsstack_copy_attr_atime(inode,
3990+ lower_file->f_path.dentry->d_inode);
3991+
3992+ if (err < 0)
3993+ goto out;
3994+
3995+ if (buf.filldir_error)
3996+ break;
3997+
3998+ if (!buf.entries_written) {
3999+ uds->bindex++;
4000+ uds->dirpos = 0;
4001+ }
4002+ }
4003+
4004+ if (!buf.filldir_error && uds->bindex >= bend) {
4005+ /* Save the number of hash entries for next time. */
4006+ UNIONFS_I(inode)->hashsize = uds->hashentries;
4007+ free_rdstate(uds);
4008+ UNIONFS_F(file)->rdstate = NULL;
4009+ file->f_pos = DIREOF;
4010+ } else {
4011+ file->f_pos = rdstate2offset(uds);
4012+ }
4013+
4014+out:
4015+ unionfs_unlock_dentry(dentry);
4016+ unionfs_read_unlock(dentry->d_sb);
4017+ return err;
4018+}
4019+
4020+/*
4021+ * This is not meant to be a generic repositioning function. If you do
4022+ * things that aren't supported, then we return EINVAL.
4023+ *
4024+ * What is allowed:
4025+ * (1) seeking to the same position that you are currently at
4026+ * This really has no effect, but returns where you are.
4027+ * (2) seeking to the beginning of the file
4028+ * This throws out all state, and lets you begin again.
4029+ */
4030+static loff_t unionfs_dir_llseek(struct file *file, loff_t offset, int origin)
4031+{
4032+ struct unionfs_dir_state *rdstate;
4033+ struct dentry *dentry = file->f_path.dentry;
4034+ loff_t err;
4035+
4036+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4037+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4038+
4039+ err = unionfs_file_revalidate(file, false);
4040+ if (unlikely(err))
4041+ goto out;
4042+
4043+ rdstate = UNIONFS_F(file)->rdstate;
4044+
4045+ /*
4046+ * we let users seek to their current position, but not anywhere
4047+ * else.
4048+ */
4049+ if (!offset) {
4050+ switch (origin) {
4051+ case SEEK_SET:
4052+ if (rdstate) {
4053+ free_rdstate(rdstate);
4054+ UNIONFS_F(file)->rdstate = NULL;
4055+ }
4056+ init_rdstate(file);
4057+ err = 0;
4058+ break;
4059+ case SEEK_CUR:
4060+ err = file->f_pos;
4061+ break;
4062+ case SEEK_END:
4063+ /* Unsupported, because we would break everything. */
4064+ err = -EINVAL;
4065+ break;
4066+ }
4067+ } else {
4068+ switch (origin) {
4069+ case SEEK_SET:
4070+ if (rdstate) {
4071+ if (offset == rdstate2offset(rdstate))
4072+ err = offset;
4073+ else if (file->f_pos == DIREOF)
4074+ err = DIREOF;
4075+ else
4076+ err = -EINVAL;
4077+ } else {
4078+ struct inode *inode;
4079+ inode = dentry->d_inode;
4080+ rdstate = find_rdstate(inode, offset);
4081+ if (rdstate) {
4082+ UNIONFS_F(file)->rdstate = rdstate;
4083+ err = rdstate->offset;
4084+ } else {
4085+ err = -EINVAL;
4086+ }
4087+ }
4088+ break;
4089+ case SEEK_CUR:
4090+ case SEEK_END:
4091+ /* Unsupported, because we would break everything. */
4092+ err = -EINVAL;
4093+ break;
4094+ }
4095+ }
4096+
4097+out:
4098+ unionfs_unlock_dentry(dentry);
4099+ unionfs_read_unlock(dentry->d_sb);
4100+ return err;
4101+}
4102+
4103+/*
4104+ * Trimmed directory options, we shouldn't pass everything down since
4105+ * we don't want to operate on partial directories.
4106+ */
4107+struct file_operations unionfs_dir_fops = {
4108+ .llseek = unionfs_dir_llseek,
4109+ .read = generic_read_dir,
4110+ .readdir = unionfs_readdir,
4111+ .unlocked_ioctl = unionfs_ioctl,
4112+ .open = unionfs_open,
4113+ .release = unionfs_file_release,
4114+ .flush = unionfs_flush,
4115+ .fsync = unionfs_fsync,
4116+ .fasync = unionfs_fasync,
4117+};
4118diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
4119new file mode 100644
4120index 0000000..d936f03
4121--- /dev/null
4122+++ b/fs/unionfs/dirhelper.c
4123@@ -0,0 +1,157 @@
4124+/*
4125+ * Copyright (c) 2003-2008 Erez Zadok
4126+ * Copyright (c) 2003-2006 Charles P. Wright
4127+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
4128+ * Copyright (c) 2005-2006 Junjiro Okajima
4129+ * Copyright (c) 2005 Arun M. Krishnakumar
4130+ * Copyright (c) 2004-2006 David P. Quigley
4131+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
4132+ * Copyright (c) 2003 Puja Gupta
4133+ * Copyright (c) 2003 Harikesavan Krishnan
4134+ * Copyright (c) 2003-2008 Stony Brook University
4135+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
4136+ *
4137+ * This program is free software; you can redistribute it and/or modify
4138+ * it under the terms of the GNU General Public License version 2 as
4139+ * published by the Free Software Foundation.
4140+ */
4141+
4142+#include "union.h"
4143+
4144+#define RD_NONE 0
4145+#define RD_CHECK_EMPTY 1
4146+/* The callback structure for check_empty. */
4147+struct unionfs_rdutil_callback {
4148+ int err;
4149+ int filldir_called;
4150+ struct unionfs_dir_state *rdstate;
4151+ int mode;
4152+};
4153+
4154+/* This filldir function makes sure only whiteouts exist within a directory. */
4155+static int readdir_util_callback(void *dirent, const char *oname, int namelen,
4156+ loff_t offset, u64 ino, unsigned int d_type)
4157+{
4158+ int err = 0;
4159+ struct unionfs_rdutil_callback *buf = dirent;
4160+ int is_whiteout;
4161+ struct filldir_node *found;
4162+ char *name = (char *) oname;
4163+
4164+ buf->filldir_called = 1;
4165+
4166+ if (name[0] == '.' && (namelen == 1 ||
4167+ (name[1] == '.' && namelen == 2)))
4168+ goto out;
4169+
4170+ is_whiteout = is_whiteout_name(&name, &namelen);
4171+
4172+ found = find_filldir_node(buf->rdstate, name, namelen, is_whiteout);
4173+ /* If it was found in the table there was a previous whiteout. */
4174+ if (found)
4175+ goto out;
4176+
4177+ /*
4178+ * if it wasn't found and isn't a whiteout, the directory isn't
4179+ * empty.
4180+ */
4181+ err = -ENOTEMPTY;
4182+ if ((buf->mode == RD_CHECK_EMPTY) && !is_whiteout)
4183+ goto out;
4184+
4185+ err = add_filldir_node(buf->rdstate, name, namelen,
4186+ buf->rdstate->bindex, is_whiteout);
4187+
4188+out:
4189+ buf->err = err;
4190+ return err;
4191+}
4192+
4193+/* Is a directory logically empty? */
4194+int check_empty(struct dentry *dentry, struct unionfs_dir_state **namelist)
4195+{
4196+ int err = 0;
4197+ struct dentry *lower_dentry = NULL;
4198+ struct vfsmount *mnt;
4199+ struct super_block *sb;
4200+ struct file *lower_file;
4201+ struct unionfs_rdutil_callback *buf = NULL;
4202+ int bindex, bstart, bend, bopaque;
4203+
4204+ sb = dentry->d_sb;
4205+
4206+
4207+ BUG_ON(!S_ISDIR(dentry->d_inode->i_mode));
4208+
4209+ err = unionfs_partial_lookup(dentry);
4210+ if (err)
4211+ goto out;
4212+
4213+ bstart = dbstart(dentry);
4214+ bend = dbend(dentry);
4215+ bopaque = dbopaque(dentry);
4216+ if (0 <= bopaque && bopaque < bend)
4217+ bend = bopaque;
4218+
4219+ buf = kmalloc(sizeof(struct unionfs_rdutil_callback), GFP_KERNEL);
4220+ if (unlikely(!buf)) {
4221+ err = -ENOMEM;
4222+ goto out;
4223+ }
4224+ buf->err = 0;
4225+ buf->mode = RD_CHECK_EMPTY;
4226+ buf->rdstate = alloc_rdstate(dentry->d_inode, bstart);
4227+ if (unlikely(!buf->rdstate)) {
4228+ err = -ENOMEM;
4229+ goto out;
4230+ }
4231+
4232+ /* Process the lower directories with rdutil_callback as a filldir. */
4233+ for (bindex = bstart; bindex <= bend; bindex++) {
4234+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
4235+ if (!lower_dentry)
4236+ continue;
4237+ if (!lower_dentry->d_inode)
4238+ continue;
4239+ if (!S_ISDIR(lower_dentry->d_inode->i_mode))
4240+ continue;
4241+
4242+ dget(lower_dentry);
4243+ mnt = unionfs_mntget(dentry, bindex);
4244+ branchget(sb, bindex);
4245+ lower_file = dentry_open(lower_dentry, mnt, O_RDONLY);
4246+ if (IS_ERR(lower_file)) {
4247+ err = PTR_ERR(lower_file);
4248+ branchput(sb, bindex);
4249+ goto out;
4250+ }
4251+
4252+ do {
4253+ buf->filldir_called = 0;
4254+ buf->rdstate->bindex = bindex;
4255+ err = vfs_readdir(lower_file,
4256+ readdir_util_callback, buf);
4257+ if (buf->err)
4258+ err = buf->err;
4259+ } while ((err >= 0) && buf->filldir_called);
4260+
4261+ /* fput calls dput for lower_dentry */
4262+ fput(lower_file);
4263+ branchput(sb, bindex);
4264+
4265+ if (err < 0)
4266+ goto out;
4267+ }
4268+
4269+out:
4270+ if (buf) {
4271+ if (namelist && !err)
4272+ *namelist = buf->rdstate;
4273+ else if (buf->rdstate)
4274+ free_rdstate(buf->rdstate);
4275+ kfree(buf);
4276+ }
4277+
4278+
4279+ return err;
4280+}
4281diff --git a/fs/unionfs/fanout.h b/fs/unionfs/fanout.h
4282new file mode 100644
4283index 0000000..4f264de
4284--- /dev/null
4285+++ b/fs/unionfs/fanout.h
4286@@ -0,0 +1,384 @@
4287+/*
4288+ * Copyright (c) 2003-2008 Erez Zadok
4289+ * Copyright (c) 2003-2006 Charles P. Wright
4290+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
4291+ * Copyright (c) 2005 Arun M. Krishnakumar
4292+ * Copyright (c) 2004-2006 David P. Quigley
4293+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
4294+ * Copyright (c) 2003 Puja Gupta
4295+ * Copyright (c) 2003 Harikesavan Krishnan
4296+ * Copyright (c) 2003-2008 Stony Brook University
4297+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
4298+ *
4299+ * This program is free software; you can redistribute it and/or modify
4300+ * it under the terms of the GNU General Public License version 2 as
4301+ * published by the Free Software Foundation.
4302+ */
4303+
4304+#ifndef _FANOUT_H_
4305+#define _FANOUT_H_
4306+
4307+/*
4308+ * Inode to private data
4309+ *
4310+ * Since we use containers and the struct inode is _inside_ the
4311+ * unionfs_inode_info structure, UNIONFS_I will always (given a non-NULL
4312+ * inode pointer), return a valid non-NULL pointer.
4313+ */
4314+static inline struct unionfs_inode_info *UNIONFS_I(const struct inode *inode)
4315+{
4316+ return container_of(inode, struct unionfs_inode_info, vfs_inode);
4317+}
4318+
4319+#define ibstart(ino) (UNIONFS_I(ino)->bstart)
4320+#define ibend(ino) (UNIONFS_I(ino)->bend)
4321+
4322+/* Dentry to private data */
4323+#define UNIONFS_D(dent) ((struct unionfs_dentry_info *)(dent)->d_fsdata)
4324+#define dbstart(dent) (UNIONFS_D(dent)->bstart)
4325+#define dbend(dent) (UNIONFS_D(dent)->bend)
4326+#define dbopaque(dent) (UNIONFS_D(dent)->bopaque)
4327+
4328+/* Superblock to private data */
4329+#define UNIONFS_SB(super) ((struct unionfs_sb_info *)(super)->s_fs_info)
4330+#define sbstart(sb) 0
4331+#define sbend(sb) (UNIONFS_SB(sb)->bend)
4332+#define sbmax(sb) (UNIONFS_SB(sb)->bend + 1)
4333+#define sbhbid(sb) (UNIONFS_SB(sb)->high_branch_id)
4334+
4335+/* File to private Data */
4336+#define UNIONFS_F(file) ((struct unionfs_file_info *)((file)->private_data))
4337+#define fbstart(file) (UNIONFS_F(file)->bstart)
4338+#define fbend(file) (UNIONFS_F(file)->bend)
4339+
4340+/* macros to manipulate branch IDs in stored in our superblock */
4341+static inline int branch_id(struct super_block *sb, int index)
4342+{
4343+ BUG_ON(!sb || index < 0);
4344+ return UNIONFS_SB(sb)->data[index].branch_id;
4345+}
4346+
4347+static inline void set_branch_id(struct super_block *sb, int index, int val)
4348+{
4349+ BUG_ON(!sb || index < 0);
4350+ UNIONFS_SB(sb)->data[index].branch_id = val;
4351+}
4352+
4353+static inline void new_branch_id(struct super_block *sb, int index)
4354+{
4355+ BUG_ON(!sb || index < 0);
4356+ set_branch_id(sb, index, ++UNIONFS_SB(sb)->high_branch_id);
4357+}
4358+
4359+/*
4360+ * Find new index of matching branch with an existing superblock of a known
4361+ * (possibly old) id. This is needed because branches could have been
4362+ * added/deleted causing the branches of any open files to shift.
4363+ *
4364+ * @sb: the new superblock which may have new/different branch IDs
4365+ * @id: the old/existing id we're looking for
4366+ * Returns index of newly found branch (0 or greater), -1 otherwise.
4367+ */
4368+static inline int branch_id_to_idx(struct super_block *sb, int id)
4369+{
4370+ int i;
4371+ for (i = 0; i < sbmax(sb); i++) {
4372+ if (branch_id(sb, i) == id)
4373+ return i;
4374+ }
4375+ /* in the non-ODF code, this should really never happen */
4376+ printk(KERN_WARNING "unionfs: cannot find branch with id %d\n", id);
4377+ return -1;
4378+}
4379+
4380+/* File to lower file. */
4381+static inline struct file *unionfs_lower_file(const struct file *f)
4382+{
4383+ BUG_ON(!f);
4384+ return UNIONFS_F(f)->lower_files[fbstart(f)];
4385+}
4386+
4387+static inline struct file *unionfs_lower_file_idx(const struct file *f,
4388+ int index)
4389+{
4390+ BUG_ON(!f || index < 0);
4391+ return UNIONFS_F(f)->lower_files[index];
4392+}
4393+
4394+static inline void unionfs_set_lower_file_idx(struct file *f, int index,
4395+ struct file *val)
4396+{
4397+ BUG_ON(!f || index < 0);
4398+ UNIONFS_F(f)->lower_files[index] = val;
4399+ /* save branch ID (may be redundant?) */
4400+ UNIONFS_F(f)->saved_branch_ids[index] =
4401+ branch_id((f)->f_path.dentry->d_sb, index);
4402+}
4403+
4404+static inline void unionfs_set_lower_file(struct file *f, struct file *val)
4405+{
4406+ BUG_ON(!f);
4407+ unionfs_set_lower_file_idx((f), fbstart(f), (val));
4408+}
4409+
4410+/* Inode to lower inode. */
4411+static inline struct inode *unionfs_lower_inode(const struct inode *i)
4412+{
4413+ BUG_ON(!i);
4414+ return UNIONFS_I(i)->lower_inodes[ibstart(i)];
4415+}
4416+
4417+static inline struct inode *unionfs_lower_inode_idx(const struct inode *i,
4418+ int index)
4419+{
4420+ BUG_ON(!i || index < 0);
4421+ return UNIONFS_I(i)->lower_inodes[index];
4422+}
4423+
4424+static inline void unionfs_set_lower_inode_idx(struct inode *i, int index,
4425+ struct inode *val)
4426+{
4427+ BUG_ON(!i || index < 0);
4428+ UNIONFS_I(i)->lower_inodes[index] = val;
4429+}
4430+
4431+static inline void unionfs_set_lower_inode(struct inode *i, struct inode *val)
4432+{
4433+ BUG_ON(!i);
4434+ UNIONFS_I(i)->lower_inodes[ibstart(i)] = val;
4435+}
4436+
4437+/* Superblock to lower superblock. */
4438+static inline struct super_block *unionfs_lower_super(
4439+ const struct super_block *sb)
4440+{
4441+ BUG_ON(!sb);
4442+ return UNIONFS_SB(sb)->data[sbstart(sb)].sb;
4443+}
4444+
4445+static inline struct super_block *unionfs_lower_super_idx(
4446+ const struct super_block *sb,
4447+ int index)
4448+{
4449+ BUG_ON(!sb || index < 0);
4450+ return UNIONFS_SB(sb)->data[index].sb;
4451+}
4452+
4453+static inline void unionfs_set_lower_super_idx(struct super_block *sb,
4454+ int index,
4455+ struct super_block *val)
4456+{
4457+ BUG_ON(!sb || index < 0);
4458+ UNIONFS_SB(sb)->data[index].sb = val;
4459+}
4460+
4461+static inline void unionfs_set_lower_super(struct super_block *sb,
4462+ struct super_block *val)
4463+{
4464+ BUG_ON(!sb);
4465+ UNIONFS_SB(sb)->data[sbstart(sb)].sb = val;
4466+}
4467+
4468+/* Branch count macros. */
4469+static inline int branch_count(const struct super_block *sb, int index)
4470+{
4471+ BUG_ON(!sb || index < 0);
4472+ return atomic_read(&UNIONFS_SB(sb)->data[index].open_files);
4473+}
4474+
4475+static inline void set_branch_count(struct super_block *sb, int index, int val)
4476+{
4477+ BUG_ON(!sb || index < 0);
4478+ atomic_set(&UNIONFS_SB(sb)->data[index].open_files, val);
4479+}
4480+
4481+static inline void branchget(struct super_block *sb, int index)
4482+{
4483+ BUG_ON(!sb || index < 0);
4484+ atomic_inc(&UNIONFS_SB(sb)->data[index].open_files);
4485+}
4486+
4487+static inline void branchput(struct super_block *sb, int index)
4488+{
4489+ BUG_ON(!sb || index < 0);
4490+ atomic_dec(&UNIONFS_SB(sb)->data[index].open_files);
4491+}
4492+
4493+/* Dentry macros */
4494+static inline void unionfs_set_lower_dentry_idx(struct dentry *dent, int index,
4495+ struct dentry *val)
4496+{
4497+ BUG_ON(!dent || index < 0);
4498+ UNIONFS_D(dent)->lower_paths[index].dentry = val;
4499+}
4500+
4501+static inline struct dentry *unionfs_lower_dentry_idx(
4502+ const struct dentry *dent,
4503+ int index)
4504+{
4505+ BUG_ON(!dent || index < 0);
4506+ return UNIONFS_D(dent)->lower_paths[index].dentry;
4507+}
4508+
4509+static inline struct dentry *unionfs_lower_dentry(const struct dentry *dent)
4510+{
4511+ BUG_ON(!dent);
4512+ return unionfs_lower_dentry_idx(dent, dbstart(dent));
4513+}
4514+
4515+static inline void unionfs_set_lower_mnt_idx(struct dentry *dent, int index,
4516+ struct vfsmount *mnt)
4517+{
4518+ BUG_ON(!dent || index < 0);
4519+ UNIONFS_D(dent)->lower_paths[index].mnt = mnt;
4520+}
4521+
4522+static inline struct vfsmount *unionfs_lower_mnt_idx(
4523+ const struct dentry *dent,
4524+ int index)
4525+{
4526+ BUG_ON(!dent || index < 0);
4527+ return UNIONFS_D(dent)->lower_paths[index].mnt;
4528+}
4529+
4530+static inline struct vfsmount *unionfs_lower_mnt(const struct dentry *dent)
4531+{
4532+ BUG_ON(!dent);
4533+ return unionfs_lower_mnt_idx(dent, dbstart(dent));
4534+}
4535+
4536+/* Macros for locking a dentry. */
4537+enum unionfs_dentry_lock_class {
4538+ UNIONFS_DMUTEX_NORMAL,
4539+ UNIONFS_DMUTEX_ROOT,
4540+ UNIONFS_DMUTEX_PARENT,
4541+ UNIONFS_DMUTEX_CHILD,
4542+ UNIONFS_DMUTEX_WHITEOUT,
4543+ UNIONFS_DMUTEX_REVAL_PARENT, /* for file/dentry revalidate */
4544+ UNIONFS_DMUTEX_REVAL_CHILD, /* for file/dentry revalidate */
4545+};
4546+
4547+static inline void unionfs_lock_dentry(struct dentry *d,
4548+ unsigned int subclass)
4549+{
4550+ BUG_ON(!d);
4551+ mutex_lock_nested(&UNIONFS_D(d)->lock, subclass);
4552+}
4553+
4554+static inline void unionfs_unlock_dentry(struct dentry *d)
4555+{
4556+ BUG_ON(!d);
4557+ mutex_unlock(&UNIONFS_D(d)->lock);
4558+}
4559+
4560+static inline void verify_locked(struct dentry *d)
4561+{
4562+ BUG_ON(!d);
4563+ BUG_ON(!mutex_is_locked(&UNIONFS_D(d)->lock));
4564+}
4565+
4566+/* macros to put lower objects */
4567+
4568+/*
4569+ * iput lower inodes of an unionfs dentry, from bstart to bend. If
4570+ * @free_lower is true, then also kfree the memory used to hold the lower
4571+ * object pointers.
4572+ */
4573+static inline void iput_lowers(struct inode *inode,
4574+ int bstart, int bend, bool free_lower)
4575+{
4576+ struct inode *lower_inode;
4577+ int bindex;
4578+
4579+ BUG_ON(!inode);
4580+ BUG_ON(!UNIONFS_I(inode));
4581+ BUG_ON(bstart < 0);
4582+
4583+ for (bindex = bstart; bindex <= bend; bindex++) {
4584+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
4585+ if (lower_inode) {
4586+ unionfs_set_lower_inode_idx(inode, bindex, NULL);
4587+ /* see Documentation/filesystems/unionfs/issues.txt */
4588+ lockdep_off();
4589+ iput(lower_inode);
4590+ lockdep_on();
4591+ }
4592+ }
4593+
4594+ if (free_lower) {
4595+ kfree(UNIONFS_I(inode)->lower_inodes);
4596+ UNIONFS_I(inode)->lower_inodes = NULL;
4597+ }
4598+}
4599+
4600+/* iput all lower inodes, and reset start/end branch indices to -1 */
4601+static inline void iput_lowers_all(struct inode *inode, bool free_lower)
4602+{
4603+ int bstart, bend;
4604+
4605+ BUG_ON(!inode);
4606+ BUG_ON(!UNIONFS_I(inode));
4607+ bstart = ibstart(inode);
4608+ bend = ibend(inode);
4609+ BUG_ON(bstart < 0);
4610+
4611+ iput_lowers(inode, bstart, bend, free_lower);
4612+ ibstart(inode) = ibend(inode) = -1;
4613+}
4614+
4615+/*
4616+ * dput/mntput all lower dentries and vfsmounts of an unionfs dentry, from
4617+ * bstart to bend. If @free_lower is true, then also kfree the memory used
4618+ * to hold the lower object pointers.
4619+ *
4620+ * XXX: implement using path_put VFS macros
4621+ */
4622+static inline void path_put_lowers(struct dentry *dentry,
4623+ int bstart, int bend, bool free_lower)
4624+{
4625+ struct dentry *lower_dentry;
4626+ struct vfsmount *lower_mnt;
4627+ int bindex;
4628+
4629+ BUG_ON(!dentry);
4630+ BUG_ON(!UNIONFS_D(dentry));
4631+ BUG_ON(bstart < 0);
4632+
4633+ for (bindex = bstart; bindex <= bend; bindex++) {
4634+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
4635+ if (lower_dentry) {
4636+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
4637+ dput(lower_dentry);
4638+ }
4639+ lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
4640+ if (lower_mnt) {
4641+ unionfs_set_lower_mnt_idx(dentry, bindex, NULL);
4642+ mntput(lower_mnt);
4643+ }
4644+ }
4645+
4646+ if (free_lower) {
4647+ kfree(UNIONFS_D(dentry)->lower_paths);
4648+ UNIONFS_D(dentry)->lower_paths = NULL;
4649+ }
4650+}
4651+
4652+/*
4653+ * dput/mntput all lower dentries and vfsmounts, and reset start/end branch
4654+ * indices to -1.
4655+ */
4656+static inline void path_put_lowers_all(struct dentry *dentry, bool free_lower)
4657+{
4658+ int bstart, bend;
4659+
4660+ BUG_ON(!dentry);
4661+ BUG_ON(!UNIONFS_D(dentry));
4662+ bstart = dbstart(dentry);
4663+ bend = dbend(dentry);
4664+ BUG_ON(bstart < 0);
4665+
4666+ path_put_lowers(dentry, bstart, bend, free_lower);
4667+ dbstart(dentry) = dbend(dentry) = -1;
4668+}
4669+
4670+#endif /* not _FANOUT_H */
4671diff --git a/fs/unionfs/file.c b/fs/unionfs/file.c
4672new file mode 100644
4673index 0000000..965d071
4674--- /dev/null
4675+++ b/fs/unionfs/file.c
4676@@ -0,0 +1,341 @@
4677+/*
4678+ * Copyright (c) 2003-2008 Erez Zadok
4679+ * Copyright (c) 2003-2006 Charles P. Wright
4680+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
4681+ * Copyright (c) 2005-2006 Junjiro Okajima
4682+ * Copyright (c) 2005 Arun M. Krishnakumar
4683+ * Copyright (c) 2004-2006 David P. Quigley
4684+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
4685+ * Copyright (c) 2003 Puja Gupta
4686+ * Copyright (c) 2003 Harikesavan Krishnan
4687+ * Copyright (c) 2003-2008 Stony Brook University
4688+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
4689+ *
4690+ * This program is free software; you can redistribute it and/or modify
4691+ * it under the terms of the GNU General Public License version 2 as
4692+ * published by the Free Software Foundation.
4693+ */
4694+
4695+#include "union.h"
4696+
4697+static ssize_t unionfs_read(struct file *file, char __user *buf,
4698+ size_t count, loff_t *ppos)
4699+{
4700+ int err;
4701+ struct file *lower_file;
4702+ struct dentry *dentry = file->f_path.dentry;
4703+
4704+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4705+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4706+ err = unionfs_file_revalidate(file, false);
4707+ if (unlikely(err))
4708+ goto out;
4709+
4710+ lower_file = unionfs_lower_file(file);
4711+ err = vfs_read(lower_file, buf, count, ppos);
4712+ /* update our inode atime upon a successful lower read */
4713+ if (err >= 0) {
4714+ fsstack_copy_attr_atime(dentry->d_inode,
4715+ lower_file->f_path.dentry->d_inode);
4716+ unionfs_check_file(file);
4717+ }
4718+
4719+out:
4720+ unionfs_unlock_dentry(dentry);
4721+ unionfs_read_unlock(dentry->d_sb);
4722+ return err;
4723+}
4724+
4725+static ssize_t unionfs_write(struct file *file, const char __user *buf,
4726+ size_t count, loff_t *ppos)
4727+{
4728+ int err = 0;
4729+ struct file *lower_file;
4730+ struct dentry *dentry = file->f_path.dentry;
4731+
4732+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4733+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4734+ if (dentry != dentry->d_parent)
4735+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT);
4736+ err = unionfs_file_revalidate_locked(file, true);
4737+ if (unlikely(err))
4738+ goto out;
4739+
4740+ lower_file = unionfs_lower_file(file);
4741+ err = vfs_write(lower_file, buf, count, ppos);
4742+ /* update our inode times+sizes upon a successful lower write */
4743+ if (err >= 0) {
4744+ fsstack_copy_inode_size(dentry->d_inode,
4745+ lower_file->f_path.dentry->d_inode);
4746+ fsstack_copy_attr_times(dentry->d_inode,
4747+ lower_file->f_path.dentry->d_inode);
4748+ UNIONFS_F(file)->wrote_to_file = true; /* for delayed copyup */
4749+ unionfs_check_file(file);
4750+ }
4751+
4752+out:
4753+ if (dentry != dentry->d_parent)
4754+ unionfs_unlock_dentry(dentry->d_parent);
4755+ unionfs_unlock_dentry(dentry);
4756+ unionfs_read_unlock(dentry->d_sb);
4757+ return err;
4758+}
4759+
4760+static int unionfs_file_readdir(struct file *file, void *dirent,
4761+ filldir_t filldir)
4762+{
4763+ return -ENOTDIR;
4764+}
4765+
4766+static int unionfs_mmap(struct file *file, struct vm_area_struct *vma)
4767+{
4768+ int err = 0;
4769+ bool willwrite;
4770+ struct file *lower_file;
4771+ struct dentry *dentry = file->f_path.dentry;
4772+ struct vm_operations_struct *saved_vm_ops = NULL;
4773+
4774+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4775+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4776+
4777+ /* This might be deferred to mmap's writepage */
4778+ willwrite = ((vma->vm_flags | VM_SHARED | VM_WRITE) == vma->vm_flags);
4779+ err = unionfs_file_revalidate(file, willwrite);
4780+ if (unlikely(err))
4781+ goto out;
4782+ unionfs_check_file(file);
4783+
4784+ /*
4785+ * File systems which do not implement ->writepage may use
4786+ * generic_file_readonly_mmap as their ->mmap op. If you call
4787+ * generic_file_readonly_mmap with VM_WRITE, you'd get an -EINVAL.
4788+ * But we cannot call the lower ->mmap op, so we can't tell that
4789+ * writeable mappings won't work. Therefore, our only choice is to
4790+ * check if the lower file system supports the ->writepage, and if
4791+ * not, return EINVAL (the same error that
4792+ * generic_file_readonly_mmap returns in that case).
4793+ */
4794+ lower_file = unionfs_lower_file(file);
4795+ if (willwrite && !lower_file->f_mapping->a_ops->writepage) {
4796+ err = -EINVAL;
4797+ printk(KERN_ERR "unionfs: branch %d file system does not "
4798+ "support writeable mmap\n", fbstart(file));
4799+ goto out;
4800+ }
4801+
4802+ /*
4803+ * find and save lower vm_ops.
4804+ *
4805+ * XXX: the VFS should have a cleaner way of finding the lower vm_ops
4806+ */
4807+ if (!UNIONFS_F(file)->lower_vm_ops) {
4808+ err = lower_file->f_op->mmap(lower_file, vma);
4809+ if (err) {
4810+ printk(KERN_ERR "unionfs: lower mmap failed %d\n", err);
4811+ goto out;
4812+ }
4813+ saved_vm_ops = vma->vm_ops;
4814+ err = do_munmap(current->mm, vma->vm_start,
4815+ vma->vm_end - vma->vm_start);
4816+ if (err) {
4817+ printk(KERN_ERR "unionfs: do_munmap failed %d\n", err);
4818+ goto out;
4819+ }
4820+ }
4821+
4822+ file->f_mapping->a_ops = &unionfs_dummy_aops;
4823+ err = generic_file_mmap(file, vma);
4824+ file->f_mapping->a_ops = &unionfs_aops;
4825+ if (err) {
4826+ printk(KERN_ERR "unionfs: generic_file_mmap failed %d\n", err);
4827+ goto out;
4828+ }
4829+ vma->vm_ops = &unionfs_vm_ops;
4830+ if (!UNIONFS_F(file)->lower_vm_ops)
4831+ UNIONFS_F(file)->lower_vm_ops = saved_vm_ops;
4832+
4833+out:
4834+ if (!err) {
4835+ /* copyup could cause parent dir times to change */
4836+ unionfs_copy_attr_times(dentry->d_parent->d_inode);
4837+ unionfs_check_file(file);
4838+ }
4839+ unionfs_unlock_dentry(dentry);
4840+ unionfs_read_unlock(dentry->d_sb);
4841+ return err;
4842+}
4843+
4844+int unionfs_fsync(struct file *file, struct dentry *dentry, int datasync)
4845+{
4846+ int bindex, bstart, bend;
4847+ struct file *lower_file;
4848+ struct dentry *lower_dentry;
4849+ struct inode *lower_inode, *inode;
4850+ int err = -EINVAL;
4851+
4852+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4853+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4854+ err = unionfs_file_revalidate(file, true);
4855+ if (unlikely(err))
4856+ goto out;
4857+ unionfs_check_file(file);
4858+
4859+ bstart = fbstart(file);
4860+ bend = fbend(file);
4861+ if (bstart < 0 || bend < 0)
4862+ goto out;
4863+
4864+ inode = dentry->d_inode;
4865+ if (unlikely(!inode)) {
4866+ printk(KERN_ERR
4867+ "unionfs: null lower inode in unionfs_fsync\n");
4868+ goto out;
4869+ }
4870+ for (bindex = bstart; bindex <= bend; bindex++) {
4871+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
4872+ if (!lower_inode || !lower_inode->i_fop->fsync)
4873+ continue;
4874+ lower_file = unionfs_lower_file_idx(file, bindex);
4875+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
4876+ mutex_lock(&lower_inode->i_mutex);
4877+ err = lower_inode->i_fop->fsync(lower_file,
4878+ lower_dentry,
4879+ datasync);
4880+ if (!err && bindex == bstart)
4881+ fsstack_copy_attr_times(inode, lower_inode);
4882+ mutex_unlock(&lower_inode->i_mutex);
4883+ if (err)
4884+ goto out;
4885+ }
4886+
4887+out:
4888+ if (!err)
4889+ unionfs_check_file(file);
4890+ unionfs_unlock_dentry(dentry);
4891+ unionfs_read_unlock(dentry->d_sb);
4892+ return err;
4893+}
4894+
4895+int unionfs_fasync(int fd, struct file *file, int flag)
4896+{
4897+ int bindex, bstart, bend;
4898+ struct file *lower_file;
4899+ struct dentry *dentry = file->f_path.dentry;
4900+ struct inode *lower_inode, *inode;
4901+ int err = 0;
4902+
4903+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4904+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4905+ err = unionfs_file_revalidate(file, true);
4906+ if (unlikely(err))
4907+ goto out;
4908+ unionfs_check_file(file);
4909+
4910+ bstart = fbstart(file);
4911+ bend = fbend(file);
4912+ if (bstart < 0 || bend < 0)
4913+ goto out;
4914+
4915+ inode = dentry->d_inode;
4916+ if (unlikely(!inode)) {
4917+ printk(KERN_ERR
4918+ "unionfs: null lower inode in unionfs_fasync\n");
4919+ goto out;
4920+ }
4921+ for (bindex = bstart; bindex <= bend; bindex++) {
4922+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
4923+ if (!lower_inode || !lower_inode->i_fop->fasync)
4924+ continue;
4925+ lower_file = unionfs_lower_file_idx(file, bindex);
4926+ mutex_lock(&lower_inode->i_mutex);
4927+ err = lower_inode->i_fop->fasync(fd, lower_file, flag);
4928+ if (!err && bindex == bstart)
4929+ fsstack_copy_attr_times(inode, lower_inode);
4930+ mutex_unlock(&lower_inode->i_mutex);
4931+ if (err)
4932+ goto out;
4933+ }
4934+
4935+out:
4936+ if (!err)
4937+ unionfs_check_file(file);
4938+ unionfs_unlock_dentry(dentry);
4939+ unionfs_read_unlock(dentry->d_sb);
4940+ return err;
4941+}
4942+
4943+static ssize_t unionfs_splice_read(struct file *file, loff_t *ppos,
4944+ struct pipe_inode_info *pipe, size_t len,
4945+ unsigned int flags)
4946+{
4947+ ssize_t err;
4948+ struct file *lower_file;
4949+ struct dentry *dentry = file->f_path.dentry;
4950+
4951+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4952+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4953+ err = unionfs_file_revalidate(file, false);
4954+ if (unlikely(err))
4955+ goto out;
4956+
4957+ lower_file = unionfs_lower_file(file);
4958+ err = vfs_splice_to(lower_file, ppos, pipe, len, flags);
4959+ /* update our inode atime upon a successful lower splice-read */
4960+ if (err >= 0) {
4961+ fsstack_copy_attr_atime(dentry->d_inode,
4962+ lower_file->f_path.dentry->d_inode);
4963+ unionfs_check_file(file);
4964+ }
4965+
4966+out:
4967+ unionfs_unlock_dentry(dentry);
4968+ unionfs_read_unlock(dentry->d_sb);
4969+ return err;
4970+}
4971+
4972+static ssize_t unionfs_splice_write(struct pipe_inode_info *pipe,
4973+ struct file *file, loff_t *ppos,
4974+ size_t len, unsigned int flags)
4975+{
4976+ ssize_t err = 0;
4977+ struct file *lower_file;
4978+ struct dentry *dentry = file->f_path.dentry;
4979+
4980+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4981+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4982+ err = unionfs_file_revalidate(file, true);
4983+ if (unlikely(err))
4984+ goto out;
4985+
4986+ lower_file = unionfs_lower_file(file);
4987+ err = vfs_splice_from(pipe, lower_file, ppos, len, flags);
4988+ /* update our inode times+sizes upon a successful lower write */
4989+ if (err >= 0) {
4990+ fsstack_copy_inode_size(dentry->d_inode,
4991+ lower_file->f_path.dentry->d_inode);
4992+ fsstack_copy_attr_times(dentry->d_inode,
4993+ lower_file->f_path.dentry->d_inode);
4994+ unionfs_check_file(file);
4995+ }
4996+
4997+out:
4998+ unionfs_unlock_dentry(dentry);
4999+ unionfs_read_unlock(dentry->d_sb);
5000+ return err;
5001+}
5002+
5003+struct file_operations unionfs_main_fops = {
5004+ .llseek = generic_file_llseek,
5005+ .read = unionfs_read,
5006+ .write = unionfs_write,
5007+ .readdir = unionfs_file_readdir,
5008+ .unlocked_ioctl = unionfs_ioctl,
5009+ .mmap = unionfs_mmap,
5010+ .open = unionfs_open,
5011+ .flush = unionfs_flush,
5012+ .release = unionfs_file_release,
5013+ .fsync = unionfs_fsync,
5014+ .fasync = unionfs_fasync,
5015+ .splice_read = unionfs_splice_read,
5016+ .splice_write = unionfs_splice_write,
5017+};
5018diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c
5019new file mode 100644
5020index 0000000..0bd9fab
5021--- /dev/null
5022+++ b/fs/unionfs/inode.c
5023@@ -0,0 +1,984 @@
5024+/*
5025+ * Copyright (c) 2003-2008 Erez Zadok
5026+ * Copyright (c) 2003-2006 Charles P. Wright
5027+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
5028+ * Copyright (c) 2005-2006 Junjiro Okajima
5029+ * Copyright (c) 2005 Arun M. Krishnakumar
5030+ * Copyright (c) 2004-2006 David P. Quigley
5031+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
5032+ * Copyright (c) 2003 Puja Gupta
5033+ * Copyright (c) 2003 Harikesavan Krishnan
5034+ * Copyright (c) 2003-2008 Stony Brook University
5035+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
5036+ *
5037+ * This program is free software; you can redistribute it and/or modify
5038+ * it under the terms of the GNU General Public License version 2 as
5039+ * published by the Free Software Foundation.
5040+ */
5041+
5042+#include "union.h"
5043+
5044+/*
5045+ * Find a writeable branch to create new object in. Checks all writeble
5046+ * branches of the parent inode, from istart to iend order; if none are
5047+ * suitable, also tries branch 0 (which may require a copyup).
5048+ *
5049+ * Return a lower_dentry we can use to create object in, or ERR_PTR.
5050+ */
5051+static struct dentry *find_writeable_branch(struct inode *parent,
5052+ struct dentry *dentry)
5053+{
5054+ int err = -EINVAL;
5055+ int bindex, istart, iend;
5056+ struct dentry *lower_dentry = NULL;
5057+
5058+ istart = ibstart(parent);
5059+ iend = ibend(parent);
5060+ if (istart < 0)
5061+ goto out;
5062+
5063+begin:
5064+ for (bindex = istart; bindex <= iend; bindex++) {
5065+ /* skip non-writeable branches */
5066+ err = is_robranch_super(dentry->d_sb, bindex);
5067+ if (err) {
5068+ err = -EROFS;
5069+ continue;
5070+ }
5071+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
5072+ if (!lower_dentry)
5073+ continue;
5074+ /*
5075+ * check for whiteouts in writeable branch, and remove them
5076+ * if necessary.
5077+ */
5078+ err = check_unlink_whiteout(dentry, lower_dentry, bindex);
5079+ if (err > 0) /* ignore if whiteout found and removed */
5080+ err = 0;
5081+ if (err)
5082+ continue;
5083+ /* if get here, we can write to the branch */
5084+ break;
5085+ }
5086+ /*
5087+ * If istart wasn't already branch 0, and we got any error, then try
5088+ * branch 0 (which may require copyup)
5089+ */
5090+ if (err && istart > 0) {
5091+ istart = iend = 0;
5092+ goto begin;
5093+ }
5094+
5095+ /*
5096+ * If we tried even branch 0, and still got an error, abort. But if
5097+ * the error was an EROFS, then we should try to copyup.
5098+ */
5099+ if (err && err != -EROFS)
5100+ goto out;
5101+
5102+ /*
5103+ * If we get here, then check if copyup needed. If lower_dentry is
5104+ * NULL, create the entire dentry directory structure in branch 0.
5105+ */
5106+ if (!lower_dentry) {
5107+ bindex = 0;
5108+ lower_dentry = create_parents(parent, dentry,
5109+ dentry->d_name.name, bindex);
5110+ if (IS_ERR(lower_dentry)) {
5111+ err = PTR_ERR(lower_dentry);
5112+ goto out;
5113+ }
5114+ }
5115+ err = 0; /* all's well */
5116+out:
5117+ if (err)
5118+ return ERR_PTR(err);
5119+ return lower_dentry;
5120+}
5121+
5122+static int unionfs_create(struct inode *parent, struct dentry *dentry,
5123+ int mode, struct nameidata *nd)
5124+{
5125+ int err = 0;
5126+ struct dentry *lower_dentry = NULL;
5127+ struct dentry *lower_parent_dentry = NULL;
5128+ int valid = 0;
5129+ struct nameidata lower_nd;
5130+
5131+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5132+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5133+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT);
5134+
5135+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, nd, false);
5136+ if (unlikely(!valid)) {
5137+ err = -ESTALE; /* same as what real_lookup does */
5138+ goto out;
5139+ }
5140+
5141+ valid = __unionfs_d_revalidate_one_locked(dentry, nd, false);
5142+ /*
5143+ * It's only a bug if this dentry was not negative and couldn't be
5144+ * revalidated (shouldn't happen).
5145+ */
5146+ BUG_ON(!valid && dentry->d_inode);
5147+
5148+ lower_dentry = find_writeable_branch(parent, dentry);
5149+ if (IS_ERR(lower_dentry)) {
5150+ err = PTR_ERR(lower_dentry);
5151+ goto out;
5152+ }
5153+
5154+ lower_parent_dentry = lock_parent(lower_dentry);
5155+ if (IS_ERR(lower_parent_dentry)) {
5156+ err = PTR_ERR(lower_parent_dentry);
5157+ goto out;
5158+ }
5159+
5160+ err = init_lower_nd(&lower_nd, LOOKUP_CREATE);
5161+ if (unlikely(err < 0))
5162+ goto out;
5163+ err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode,
5164+ &lower_nd);
5165+ release_lower_nd(&lower_nd, err);
5166+
5167+ if (!err) {
5168+ err = PTR_ERR(unionfs_interpose(dentry, parent->i_sb, 0));
5169+ if (!err) {
5170+ unionfs_copy_attr_times(parent);
5171+ fsstack_copy_inode_size(parent,
5172+ lower_parent_dentry->d_inode);
5173+ /* update no. of links on parent directory */
5174+ parent->i_nlink = unionfs_get_nlinks(parent);
5175+ }
5176+ }
5177+
5178+ unlock_dir(lower_parent_dentry);
5179+
5180+out:
5181+ if (!err) {
5182+ unionfs_postcopyup_setmnt(dentry);
5183+ unionfs_check_inode(parent);
5184+ unionfs_check_dentry(dentry);
5185+ unionfs_check_nd(nd);
5186+ }
5187+ unionfs_unlock_dentry(dentry->d_parent);
5188+ unionfs_unlock_dentry(dentry);
5189+ unionfs_read_unlock(dentry->d_sb);
5190+ return err;
5191+}
5192+
5193+/*
5194+ * unionfs_lookup is the only special function which takes a dentry, yet we
5195+ * do NOT want to call __unionfs_d_revalidate_chain because by definition,
5196+ * we don't have a valid dentry here yet.
5197+ */
5198+static struct dentry *unionfs_lookup(struct inode *parent,
5199+ struct dentry *dentry,
5200+ struct nameidata *nd)
5201+{
5202+ struct path path_save = {NULL, NULL};
5203+ struct dentry *ret;
5204+ int err = 0;
5205+
5206+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5207+ if (dentry != dentry->d_parent)
5208+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_ROOT);
5209+
5210+ /* save the dentry & vfsmnt from namei */
5211+ if (nd) {
5212+ path_save.dentry = nd->path.dentry;
5213+ path_save.mnt = nd->path.mnt;
5214+ }
5215+
5216+ /*
5217+ * unionfs_lookup_backend returns a locked dentry upon success,
5218+ * so we'll have to unlock it below.
5219+ */
5220+
5221+ /* allocate dentry private data. We free it in ->d_release */
5222+ err = new_dentry_private_data(dentry, UNIONFS_DMUTEX_CHILD);
5223+ if (unlikely(err)) {
5224+ ret = ERR_PTR(err);
5225+ goto out;
5226+ }
5227+ ret = unionfs_lookup_full(dentry, nd, INTERPOSE_LOOKUP);
5228+
5229+ /* restore the dentry & vfsmnt in namei */
5230+ if (nd) {
5231+ nd->path.dentry = path_save.dentry;
5232+ nd->path.mnt = path_save.mnt;
5233+ }
5234+ if (!IS_ERR(ret)) {
5235+ if (ret)
5236+ dentry = ret;
5237+ /* lookup_full can return multiple positive dentries */
5238+ if (dentry->d_inode && !S_ISDIR(dentry->d_inode->i_mode)) {
5239+ BUG_ON(dbstart(dentry) < 0);
5240+ unionfs_postcopyup_release(dentry);
5241+ }
5242+ unionfs_copy_attr_times(dentry->d_inode);
5243+ /* parent times may have changed */
5244+ unionfs_copy_attr_times(dentry->d_parent->d_inode);
5245+ }
5246+
5247+ unionfs_check_inode(parent);
5248+ if (!IS_ERR(ret)) {
5249+ unionfs_check_dentry(dentry);
5250+ unionfs_check_nd(nd);
5251+ }
5252+ unionfs_unlock_dentry(dentry);
5253+
5254+out:
5255+ if (dentry != dentry->d_parent) {
5256+ unionfs_check_dentry(dentry->d_parent);
5257+ unionfs_unlock_dentry(dentry->d_parent);
5258+ }
5259+ unionfs_read_unlock(dentry->d_sb);
5260+
5261+ return ret;
5262+}
5263+
5264+static int unionfs_link(struct dentry *old_dentry, struct inode *dir,
5265+ struct dentry *new_dentry)
5266+{
5267+ int err = 0;
5268+ struct dentry *lower_old_dentry = NULL;
5269+ struct dentry *lower_new_dentry = NULL;
5270+ struct dentry *lower_dir_dentry = NULL;
5271+ char *name = NULL;
5272+
5273+ unionfs_read_lock(old_dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5274+ unionfs_double_lock_dentry(new_dentry, old_dentry);
5275+
5276+ if (unlikely(!__unionfs_d_revalidate_chain(old_dentry, NULL, false))) {
5277+ err = -ESTALE;
5278+ goto out;
5279+ }
5280+ if (unlikely(new_dentry->d_inode &&
5281+ !__unionfs_d_revalidate_chain(new_dentry, NULL, false))) {
5282+ err = -ESTALE;
5283+ goto out;
5284+ }
5285+
5286+ lower_new_dentry = unionfs_lower_dentry(new_dentry);
5287+
5288+ /* check for a whiteout in new dentry branch, and delete it */
5289+ err = check_unlink_whiteout(new_dentry, lower_new_dentry,
5290+ dbstart(new_dentry));
5291+ if (err > 0) { /* whiteout found and removed successfully */
5292+ lower_dir_dentry = dget_parent(lower_new_dentry);
5293+ fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
5294+ dput(lower_dir_dentry);
5295+ dir->i_nlink = unionfs_get_nlinks(dir);
5296+ err = 0;
5297+ }
5298+ if (err)
5299+ goto out;
5300+
5301+ /* check if parent hierachy is needed, then link in same branch */
5302+ if (dbstart(old_dentry) != dbstart(new_dentry)) {
5303+ lower_new_dentry = create_parents(dir, new_dentry,
5304+ new_dentry->d_name.name,
5305+ dbstart(old_dentry));
5306+ err = PTR_ERR(lower_new_dentry);
5307+ if (IS_COPYUP_ERR(err))
5308+ goto docopyup;
5309+ if (!lower_new_dentry || IS_ERR(lower_new_dentry))
5310+ goto out;
5311+ }
5312+ lower_new_dentry = unionfs_lower_dentry(new_dentry);
5313+ lower_old_dentry = unionfs_lower_dentry(old_dentry);
5314+
5315+ BUG_ON(dbstart(old_dentry) != dbstart(new_dentry));
5316+ lower_dir_dentry = lock_parent(lower_new_dentry);
5317+ err = is_robranch(old_dentry);
5318+ if (!err) {
5319+ /* see Documentation/filesystems/unionfs/issues.txt */
5320+ lockdep_off();
5321+ err = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
5322+ lower_new_dentry);
5323+ lockdep_on();
5324+ }
5325+ unlock_dir(lower_dir_dentry);
5326+
5327+docopyup:
5328+ if (IS_COPYUP_ERR(err)) {
5329+ int old_bstart = dbstart(old_dentry);
5330+ int bindex;
5331+
5332+ for (bindex = old_bstart - 1; bindex >= 0; bindex--) {
5333+ err = copyup_dentry(old_dentry->d_parent->d_inode,
5334+ old_dentry, old_bstart,
5335+ bindex, old_dentry->d_name.name,
5336+ old_dentry->d_name.len, NULL,
5337+ i_size_read(old_dentry->d_inode));
5338+ if (err)
5339+ continue;
5340+ lower_new_dentry =
5341+ create_parents(dir, new_dentry,
5342+ new_dentry->d_name.name,
5343+ bindex);
5344+ lower_old_dentry = unionfs_lower_dentry(old_dentry);
5345+ lower_dir_dentry = lock_parent(lower_new_dentry);
5346+ /* see Documentation/filesystems/unionfs/issues.txt */
5347+ lockdep_off();
5348+ /* do vfs_link */
5349+ err = vfs_link(lower_old_dentry,
5350+ lower_dir_dentry->d_inode,
5351+ lower_new_dentry);
5352+ lockdep_on();
5353+ unlock_dir(lower_dir_dentry);
5354+ goto check_link;
5355+ }
5356+ goto out;
5357+ }
5358+
5359+check_link:
5360+ if (err || !lower_new_dentry->d_inode)
5361+ goto out;
5362+
5363+ /* Its a hard link, so use the same inode */
5364+ new_dentry->d_inode = igrab(old_dentry->d_inode);
5365+ d_add(new_dentry, new_dentry->d_inode);
5366+ unionfs_copy_attr_all(dir, lower_new_dentry->d_parent->d_inode);
5367+ fsstack_copy_inode_size(dir, lower_new_dentry->d_parent->d_inode);
5368+
5369+ /* propagate number of hard-links */
5370+ old_dentry->d_inode->i_nlink = unionfs_get_nlinks(old_dentry->d_inode);
5371+ /* new dentry's ctime may have changed due to hard-link counts */
5372+ unionfs_copy_attr_times(new_dentry->d_inode);
5373+
5374+out:
5375+ if (!new_dentry->d_inode)
5376+ d_drop(new_dentry);
5377+
5378+ kfree(name);
5379+ if (!err)
5380+ unionfs_postcopyup_setmnt(new_dentry);
5381+
5382+ unionfs_check_inode(dir);
5383+ unionfs_check_dentry(new_dentry);
5384+ unionfs_check_dentry(old_dentry);
5385+
5386+ unionfs_unlock_dentry(new_dentry);
5387+ unionfs_unlock_dentry(old_dentry);
5388+ unionfs_read_unlock(old_dentry->d_sb);
5389+
5390+ return err;
5391+}
5392+
5393+static int unionfs_symlink(struct inode *parent, struct dentry *dentry,
5394+ const char *symname)
5395+{
5396+ int err = 0;
5397+ struct dentry *lower_dentry = NULL;
5398+ struct dentry *wh_dentry = NULL;
5399+ struct dentry *lower_parent_dentry = NULL;
5400+ char *name = NULL;
5401+ int valid = 0;
5402+ umode_t mode;
5403+
5404+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5405+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5406+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT);
5407+
5408+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, NULL, false);
5409+ if (unlikely(!valid)) {
5410+ err = -ESTALE;
5411+ goto out;
5412+ }
5413+ if (unlikely(dentry->d_inode &&
5414+ !__unionfs_d_revalidate_one_locked(dentry, NULL, false))) {
5415+ err = -ESTALE;
5416+ goto out;
5417+ }
5418+
5419+ /*
5420+ * It's only a bug if this dentry was not negative and couldn't be
5421+ * revalidated (shouldn't happen).
5422+ */
5423+ BUG_ON(!valid && dentry->d_inode);
5424+
5425+ lower_dentry = find_writeable_branch(parent, dentry);
5426+ if (IS_ERR(lower_dentry)) {
5427+ err = PTR_ERR(lower_dentry);
5428+ goto out;
5429+ }
5430+
5431+ lower_parent_dentry = lock_parent(lower_dentry);
5432+ if (IS_ERR(lower_parent_dentry)) {
5433+ err = PTR_ERR(lower_parent_dentry);
5434+ goto out;
5435+ }
5436+
5437+ mode = S_IALLUGO;
5438+ err = vfs_symlink(lower_parent_dentry->d_inode, lower_dentry, symname);
5439+ if (!err) {
5440+ err = PTR_ERR(unionfs_interpose(dentry, parent->i_sb, 0));
5441+ if (!err) {
5442+ unionfs_copy_attr_times(parent);
5443+ fsstack_copy_inode_size(parent,
5444+ lower_parent_dentry->d_inode);
5445+ /* update no. of links on parent directory */
5446+ parent->i_nlink = unionfs_get_nlinks(parent);
5447+ }
5448+ }
5449+
5450+ unlock_dir(lower_parent_dentry);
5451+
5452+out:
5453+ dput(wh_dentry);
5454+ kfree(name);
5455+
5456+ if (!err) {
5457+ unionfs_postcopyup_setmnt(dentry);
5458+ unionfs_check_inode(parent);
5459+ unionfs_check_dentry(dentry);
5460+ }
5461+ unionfs_unlock_dentry(dentry->d_parent);
5462+ unionfs_unlock_dentry(dentry);
5463+ unionfs_read_unlock(dentry->d_sb);
5464+ return err;
5465+}
5466+
5467+static int unionfs_mkdir(struct inode *parent, struct dentry *dentry, int mode)
5468+{
5469+ int err = 0;
5470+ struct dentry *lower_dentry = NULL;
5471+ struct dentry *lower_parent_dentry = NULL;
5472+ int bindex = 0, bstart;
5473+ char *name = NULL;
5474+ int valid;
5475+
5476+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5477+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5478+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT);
5479+
5480+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, NULL, false);
5481+ if (unlikely(!valid)) {
5482+ err = -ESTALE; /* same as what real_lookup does */
5483+ goto out;
5484+ }
5485+ if (unlikely(dentry->d_inode &&
5486+ !__unionfs_d_revalidate_one_locked(dentry, NULL, false))) {
5487+ err = -ESTALE;
5488+ goto out;
5489+ }
5490+
5491+ bstart = dbstart(dentry);
5492+
5493+ lower_dentry = unionfs_lower_dentry(dentry);
5494+
5495+ /* check for a whiteout in new dentry branch, and delete it */
5496+ err = check_unlink_whiteout(dentry, lower_dentry, bstart);
5497+ if (err > 0) /* whiteout found and removed successfully */
5498+ err = 0;
5499+ if (err) {
5500+ /* exit if the error returned was NOT -EROFS */
5501+ if (!IS_COPYUP_ERR(err))
5502+ goto out;
5503+ bstart--;
5504+ }
5505+
5506+ /* check if copyup's needed, and mkdir */
5507+ for (bindex = bstart; bindex >= 0; bindex--) {
5508+ int i;
5509+ int bend = dbend(dentry);
5510+
5511+ if (is_robranch_super(dentry->d_sb, bindex))
5512+ continue;
5513+
5514+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
5515+ if (!lower_dentry) {
5516+ lower_dentry = create_parents(parent, dentry,
5517+ dentry->d_name.name,
5518+ bindex);
5519+ if (!lower_dentry || IS_ERR(lower_dentry)) {
5520+ printk(KERN_ERR "unionfs: lower dentry "
5521+ " NULL for bindex = %d\n", bindex);
5522+ continue;
5523+ }
5524+ }
5525+
5526+ lower_parent_dentry = lock_parent(lower_dentry);
5527+
5528+ if (IS_ERR(lower_parent_dentry)) {
5529+ err = PTR_ERR(lower_parent_dentry);
5530+ goto out;
5531+ }
5532+
5533+ err = vfs_mkdir(lower_parent_dentry->d_inode, lower_dentry,
5534+ mode);
5535+
5536+ unlock_dir(lower_parent_dentry);
5537+
5538+ /* did the mkdir succeed? */
5539+ if (err)
5540+ break;
5541+
5542+ for (i = bindex + 1; i < bend; i++) {
5543+ if (unionfs_lower_dentry_idx(dentry, i)) {
5544+ dput(unionfs_lower_dentry_idx(dentry, i));
5545+ unionfs_set_lower_dentry_idx(dentry, i, NULL);
5546+ }
5547+ }
5548+ dbend(dentry) = bindex;
5549+
5550+ /*
5551+ * Only INTERPOSE_LOOKUP can return a value other than 0 on
5552+ * err.
5553+ */
5554+ err = PTR_ERR(unionfs_interpose(dentry, parent->i_sb, 0));
5555+ if (!err) {
5556+ unionfs_copy_attr_times(parent);
5557+ fsstack_copy_inode_size(parent,
5558+ lower_parent_dentry->d_inode);
5559+
5560+ /* update number of links on parent directory */
5561+ parent->i_nlink = unionfs_get_nlinks(parent);
5562+ }
5563+
5564+ err = make_dir_opaque(dentry, dbstart(dentry));
5565+ if (err) {
5566+ printk(KERN_ERR "unionfs: mkdir: error creating "
5567+ ".wh.__dir_opaque: %d\n", err);
5568+ goto out;
5569+ }
5570+
5571+ /* we are done! */
5572+ break;
5573+ }
5574+
5575+out:
5576+ if (!dentry->d_inode)
5577+ d_drop(dentry);
5578+
5579+ kfree(name);
5580+
5581+ if (!err) {
5582+ unionfs_copy_attr_times(dentry->d_inode);
5583+ unionfs_postcopyup_setmnt(dentry);
5584+ }
5585+ unionfs_check_inode(parent);
5586+ unionfs_check_dentry(dentry);
5587+ unionfs_unlock_dentry(dentry->d_parent);
5588+ unionfs_unlock_dentry(dentry);
5589+ unionfs_read_unlock(dentry->d_sb);
5590+
5591+ return err;
5592+}
5593+
5594+static int unionfs_mknod(struct inode *parent, struct dentry *dentry, int mode,
5595+ dev_t dev)
5596+{
5597+ int err = 0;
5598+ struct dentry *lower_dentry = NULL;
5599+ struct dentry *wh_dentry = NULL;
5600+ struct dentry *lower_parent_dentry = NULL;
5601+ char *name = NULL;
5602+ int valid = 0;
5603+
5604+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5605+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5606+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT);
5607+
5608+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, NULL, false);
5609+ if (unlikely(!valid)) {
5610+ err = -ESTALE;
5611+ goto out;
5612+ }
5613+ if (unlikely(dentry->d_inode &&
5614+ !__unionfs_d_revalidate_one_locked(dentry, NULL, false))) {
5615+ err = -ESTALE;
5616+ goto out;
5617+ }
5618+
5619+ /*
5620+ * It's only a bug if this dentry was not negative and couldn't be
5621+ * revalidated (shouldn't happen).
5622+ */
5623+ BUG_ON(!valid && dentry->d_inode);
5624+
5625+ lower_dentry = find_writeable_branch(parent, dentry);
5626+ if (IS_ERR(lower_dentry)) {
5627+ err = PTR_ERR(lower_dentry);
5628+ goto out;
5629+ }
5630+
5631+ lower_parent_dentry = lock_parent(lower_dentry);
5632+ if (IS_ERR(lower_parent_dentry)) {
5633+ err = PTR_ERR(lower_parent_dentry);
5634+ goto out;
5635+ }
5636+
5637+ err = vfs_mknod(lower_parent_dentry->d_inode, lower_dentry, mode, dev);
5638+ if (!err) {
5639+ err = PTR_ERR(unionfs_interpose(dentry, parent->i_sb, 0));
5640+ if (!err) {
5641+ unionfs_copy_attr_times(parent);
5642+ fsstack_copy_inode_size(parent,
5643+ lower_parent_dentry->d_inode);
5644+ /* update no. of links on parent directory */
5645+ parent->i_nlink = unionfs_get_nlinks(parent);
5646+ }
5647+ }
5648+
5649+ unlock_dir(lower_parent_dentry);
5650+
5651+out:
5652+ dput(wh_dentry);
5653+ kfree(name);
5654+
5655+ if (!err) {
5656+ unionfs_postcopyup_setmnt(dentry);
5657+ unionfs_check_inode(parent);
5658+ unionfs_check_dentry(dentry);
5659+ }
5660+ unionfs_unlock_dentry(dentry->d_parent);
5661+ unionfs_unlock_dentry(dentry);
5662+ unionfs_read_unlock(dentry->d_sb);
5663+ return err;
5664+}
5665+
5666+static int unionfs_readlink(struct dentry *dentry, char __user *buf,
5667+ int bufsiz)
5668+{
5669+ int err;
5670+ struct dentry *lower_dentry;
5671+
5672+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5673+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5674+
5675+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
5676+ err = -ESTALE;
5677+ goto out;
5678+ }
5679+
5680+ lower_dentry = unionfs_lower_dentry(dentry);
5681+
5682+ if (!lower_dentry->d_inode->i_op ||
5683+ !lower_dentry->d_inode->i_op->readlink) {
5684+ err = -EINVAL;
5685+ goto out;
5686+ }
5687+
5688+ err = lower_dentry->d_inode->i_op->readlink(lower_dentry,
5689+ buf, bufsiz);
5690+ if (err > 0)
5691+ fsstack_copy_attr_atime(dentry->d_inode,
5692+ lower_dentry->d_inode);
5693+
5694+out:
5695+ unionfs_check_dentry(dentry);
5696+ unionfs_unlock_dentry(dentry);
5697+ unionfs_read_unlock(dentry->d_sb);
5698+
5699+ return err;
5700+}
5701+
5702+/*
5703+ * unionfs_follow_link takes a dentry, but it is simple. It only needs to
5704+ * allocate some memory and then call our ->readlink method. Our
5705+ * unionfs_readlink *does* lock our dentry and revalidate the dentry.
5706+ * Therefore, we do not have to lock our dentry here, to prevent a deadlock;
5707+ * nor do we need to revalidate it either. It is safe to not lock our
5708+ * dentry here, nor revalidate it, because unionfs_follow_link does not do
5709+ * anything (prior to calling ->readlink) which could become inconsistent
5710+ * due to branch management. We also don't need to lock our super because
5711+ * this function isn't affected by branch-management.
5712+ */
5713+static void *unionfs_follow_link(struct dentry *dentry, struct nameidata *nd)
5714+{
5715+ char *buf;
5716+ int len = PAGE_SIZE, err;
5717+ mm_segment_t old_fs;
5718+
5719+ /* This is freed by the put_link method assuming a successful call. */
5720+ buf = kmalloc(len, GFP_KERNEL);
5721+ if (unlikely(!buf)) {
5722+ err = -ENOMEM;
5723+ goto out;
5724+ }
5725+
5726+ /* read the symlink, and then we will follow it */
5727+ old_fs = get_fs();
5728+ set_fs(KERNEL_DS);
5729+ err = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len);
5730+ set_fs(old_fs);
5731+ if (err < 0) {
5732+ kfree(buf);
5733+ buf = NULL;
5734+ goto out;
5735+ }
5736+ buf[err] = 0;
5737+ nd_set_link(nd, buf);
5738+ err = 0;
5739+
5740+out:
5741+ if (!err) {
5742+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5743+ unionfs_check_dentry(dentry);
5744+ unionfs_unlock_dentry(dentry);
5745+ }
5746+ unionfs_check_nd(nd);
5747+ return ERR_PTR(err);
5748+}
5749+
5750+/* FIXME: We may not have to lock here */
5751+static void unionfs_put_link(struct dentry *dentry, struct nameidata *nd,
5752+ void *cookie)
5753+{
5754+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5755+
5756+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5757+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, nd, false)))
5758+ printk(KERN_ERR
5759+ "unionfs: put_link failed to revalidate dentry\n");
5760+
5761+ unionfs_check_dentry(dentry);
5762+ unionfs_check_nd(nd);
5763+ kfree(nd_get_link(nd));
5764+ unionfs_unlock_dentry(dentry);
5765+ unionfs_read_unlock(dentry->d_sb);
5766+}
5767+
5768+/*
5769+ * Don't grab the superblock read-lock in unionfs_permission, which prevents
5770+ * a deadlock with the branch-management "add branch" code (which grabbed
5771+ * the write lock). It is safe to not grab the read lock here, because even
5772+ * with branch management taking place, there is no chance that
5773+ * unionfs_permission, or anything it calls, will use stale branch
5774+ * information.
5775+ */
5776+static int unionfs_permission(struct inode *inode, int mask)
5777+{
5778+ struct inode *lower_inode = NULL;
5779+ int err = 0;
5780+ int bindex, bstart, bend;
5781+ const int is_file = !S_ISDIR(inode->i_mode);
5782+ const int write_mask = (mask & MAY_WRITE) && !(mask & MAY_READ);
5783+
5784+ if (!UNIONFS_I(inode)->lower_inodes) {
5785+ if (is_file) /* dirs can be unlinked but chdir'ed to */
5786+ err = -ESTALE; /* force revalidate */
5787+ goto out;
5788+ }
5789+ bstart = ibstart(inode);
5790+ bend = ibend(inode);
5791+ if (unlikely(bstart < 0 || bend < 0)) {
5792+ /*
5793+ * With branch-management, we can get a stale inode here.
5794+ * If so, we return ESTALE back to link_path_walk, which
5795+ * would discard the dcache entry and re-lookup the
5796+ * dentry+inode. This should be equivalent to issuing
5797+ * __unionfs_d_revalidate_chain on nd.dentry here.
5798+ */
5799+ if (is_file) /* dirs can be unlinked but chdir'ed to */
5800+ err = -ESTALE; /* force revalidate */
5801+ goto out;
5802+ }
5803+
5804+ for (bindex = bstart; bindex <= bend; bindex++) {
5805+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
5806+ if (!lower_inode)
5807+ continue;
5808+
5809+ /*
5810+ * check the condition for D-F-D underlying files/directories,
5811+ * we don't have to check for files, if we are checking for
5812+ * directories.
5813+ */
5814+ if (!is_file && !S_ISDIR(lower_inode->i_mode))
5815+ continue;
5816+
5817+ /*
5818+ * We check basic permissions, but we ignore any conditions
5819+ * such as readonly file systems or branches marked as
5820+ * readonly, because those conditions should lead to a
5821+ * copyup taking place later on.
5822+ */
5823+ err = inode_permission(lower_inode, mask);
5824+ if (err && bindex > 0) {
5825+ umode_t mode = lower_inode->i_mode;
5826+ if (is_robranch_super(inode->i_sb, bindex) &&
5827+ (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
5828+ err = 0;
5829+ if (IS_COPYUP_ERR(err))
5830+ err = 0;
5831+ }
5832+
5833+ /*
5834+ * The permissions are an intersection of the overall directory
5835+ * permissions, so we fail if one fails.
5836+ */
5837+ if (err)
5838+ goto out;
5839+
5840+ /* only the leftmost file matters. */
5841+ if (is_file || write_mask) {
5842+ if (is_file && write_mask) {
5843+ err = get_write_access(lower_inode);
5844+ if (!err)
5845+ put_write_access(lower_inode);
5846+ }
5847+ break;
5848+ }
5849+ }
5850+ /* sync times which may have changed (asynchronously) below */
5851+ unionfs_copy_attr_times(inode);
5852+
5853+out:
5854+ unionfs_check_inode(inode);
5855+ return err;
5856+}
5857+
5858+static int unionfs_setattr(struct dentry *dentry, struct iattr *ia)
5859+{
5860+ int err = 0;
5861+ struct dentry *lower_dentry;
5862+ struct inode *inode;
5863+ struct inode *lower_inode;
5864+ int bstart, bend, bindex;
5865+ loff_t size;
5866+
5867+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5868+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5869+
5870+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
5871+ err = -ESTALE;
5872+ goto out;
5873+ }
5874+
5875+ bstart = dbstart(dentry);
5876+ bend = dbend(dentry);
5877+ inode = dentry->d_inode;
5878+
5879+ /*
5880+ * mode change is for clearing setuid/setgid. Allow lower filesystem
5881+ * to reinterpret it in its own way.
5882+ */
5883+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
5884+ ia->ia_valid &= ~ATTR_MODE;
5885+
5886+ lower_dentry = unionfs_lower_dentry(dentry);
5887+ BUG_ON(!lower_dentry); /* should never happen after above revalidate */
5888+
5889+ /* copyup if the file is on a read only branch */
5890+ if (is_robranch_super(dentry->d_sb, bstart)
5891+ || IS_RDONLY(lower_dentry->d_inode)) {
5892+ /* check if we have a branch to copy up to */
5893+ if (bstart <= 0) {
5894+ err = -EACCES;
5895+ goto out;
5896+ }
5897+
5898+ if (ia->ia_valid & ATTR_SIZE)
5899+ size = ia->ia_size;
5900+ else
5901+ size = i_size_read(inode);
5902+ /* copyup to next available branch */
5903+ for (bindex = bstart - 1; bindex >= 0; bindex--) {
5904+ err = copyup_dentry(dentry->d_parent->d_inode,
5905+ dentry, bstart, bindex,
5906+ dentry->d_name.name,
5907+ dentry->d_name.len,
5908+ NULL, size);
5909+ if (!err)
5910+ break;
5911+ }
5912+ if (err)
5913+ goto out;
5914+ /* get updated lower_dentry after copyup */
5915+ lower_dentry = unionfs_lower_dentry(dentry);
5916+ }
5917+
5918+ lower_inode = unionfs_lower_inode(inode);
5919+
5920+ /*
5921+ * If shrinking, first truncate upper level to cancel writing dirty
5922+ * pages beyond the new eof; and also if its' maxbytes is more
5923+ * limiting (fail with -EFBIG before making any change to the lower
5924+ * level). There is no need to vmtruncate the upper level
5925+ * afterwards in the other cases: we fsstack_copy_inode_size from
5926+ * the lower level.
5927+ */
5928+ if (ia->ia_valid & ATTR_SIZE) {
5929+ size = i_size_read(inode);
5930+ if (ia->ia_size < size || (ia->ia_size > size &&
5931+ inode->i_sb->s_maxbytes < lower_inode->i_sb->s_maxbytes)) {
5932+ err = vmtruncate(inode, ia->ia_size);
5933+ if (err)
5934+ goto out;
5935+ }
5936+ }
5937+
5938+ /* notify the (possibly copied-up) lower inode */
5939+ mutex_lock(&lower_dentry->d_inode->i_mutex);
5940+ err = notify_change(lower_dentry, ia);
5941+ mutex_unlock(&lower_dentry->d_inode->i_mutex);
5942+ if (err)
5943+ goto out;
5944+
5945+ /* get attributes from the first lower inode */
5946+ unionfs_copy_attr_all(inode, lower_inode);
5947+ /*
5948+ * unionfs_copy_attr_all will copy the lower times to our inode if
5949+ * the lower ones are newer (useful for cache coherency). However,
5950+ * ->setattr is the only place in which we may have to copy the
5951+ * lower inode times absolutely, to support utimes(2).
5952+ */
5953+ if (ia->ia_valid & ATTR_MTIME_SET)
5954+ inode->i_mtime = lower_inode->i_mtime;
5955+ if (ia->ia_valid & ATTR_CTIME)
5956+ inode->i_ctime = lower_inode->i_ctime;
5957+ if (ia->ia_valid & ATTR_ATIME_SET)
5958+ inode->i_atime = lower_inode->i_atime;
5959+ fsstack_copy_inode_size(inode, lower_inode);
5960+
5961+out:
5962+ if (!err)
5963+ unionfs_check_dentry(dentry);
5964+ unionfs_unlock_dentry(dentry);
5965+ unionfs_read_unlock(dentry->d_sb);
5966+
5967+ return err;
5968+}
5969+
5970+struct inode_operations unionfs_symlink_iops = {
5971+ .readlink = unionfs_readlink,
5972+ .permission = unionfs_permission,
5973+ .follow_link = unionfs_follow_link,
5974+ .setattr = unionfs_setattr,
5975+ .put_link = unionfs_put_link,
5976+};
5977+
5978+struct inode_operations unionfs_dir_iops = {
5979+ .create = unionfs_create,
5980+ .lookup = unionfs_lookup,
5981+ .link = unionfs_link,
5982+ .unlink = unionfs_unlink,
5983+ .symlink = unionfs_symlink,
5984+ .mkdir = unionfs_mkdir,
5985+ .rmdir = unionfs_rmdir,
5986+ .mknod = unionfs_mknod,
5987+ .rename = unionfs_rename,
5988+ .permission = unionfs_permission,
5989+ .setattr = unionfs_setattr,
5990+#ifdef CONFIG_UNION_FS_XATTR
5991+ .setxattr = unionfs_setxattr,
5992+ .getxattr = unionfs_getxattr,
5993+ .removexattr = unionfs_removexattr,
5994+ .listxattr = unionfs_listxattr,
5995+#endif /* CONFIG_UNION_FS_XATTR */
5996+};
5997+
5998+struct inode_operations unionfs_main_iops = {
5999+ .permission = unionfs_permission,
6000+ .setattr = unionfs_setattr,
6001+#ifdef CONFIG_UNION_FS_XATTR
6002+ .setxattr = unionfs_setxattr,
6003+ .getxattr = unionfs_getxattr,
6004+ .removexattr = unionfs_removexattr,
6005+ .listxattr = unionfs_listxattr,
6006+#endif /* CONFIG_UNION_FS_XATTR */
6007+};
6008diff --git a/fs/unionfs/lookup.c b/fs/unionfs/lookup.c
6009new file mode 100644
6010index 0000000..0a9602a
6011--- /dev/null
6012+++ b/fs/unionfs/lookup.c
6013@@ -0,0 +1,570 @@
6014+/*
6015+ * Copyright (c) 2003-2008 Erez Zadok
6016+ * Copyright (c) 2003-2006 Charles P. Wright
6017+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
6018+ * Copyright (c) 2005-2006 Junjiro Okajima
6019+ * Copyright (c) 2005 Arun M. Krishnakumar
6020+ * Copyright (c) 2004-2006 David P. Quigley
6021+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
6022+ * Copyright (c) 2003 Puja Gupta
6023+ * Copyright (c) 2003 Harikesavan Krishnan
6024+ * Copyright (c) 2003-2008 Stony Brook University
6025+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
6026+ *
6027+ * This program is free software; you can redistribute it and/or modify
6028+ * it under the terms of the GNU General Public License version 2 as
6029+ * published by the Free Software Foundation.
6030+ */
6031+
6032+#include "union.h"
6033+
6034+/*
6035+ * Lookup one path component @name relative to a <base,mnt> path pair.
6036+ * Behaves nearly the same as lookup_one_len (i.e., return negative dentry
6037+ * on ENOENT), but uses the @mnt passed, so it can cross bind mounts and
6038+ * other lower mounts properly. If @new_mnt is non-null, will fill in the
6039+ * new mnt there. Caller is responsible to dput/mntput/path_put returned
6040+ * @dentry and @new_mnt.
6041+ */
6042+struct dentry *__lookup_one(struct dentry *base, struct vfsmount *mnt,
6043+ const char *name, struct vfsmount **new_mnt)
6044+{
6045+ struct dentry *dentry = NULL;
6046+ struct nameidata lower_nd;
6047+ int err;
6048+
6049+ /* we use flags=0 to get basic lookup */
6050+ err = vfs_path_lookup(base, mnt, name, 0, &lower_nd);
6051+
6052+ switch (err) {
6053+ case 0: /* no error */
6054+ dentry = lower_nd.path.dentry;
6055+ if (new_mnt)
6056+ *new_mnt = lower_nd.path.mnt; /* rc already inc'ed */
6057+ break;
6058+ case -ENOENT:
6059+ /*
6060+ * We don't consider ENOENT an error, and we want to return
6061+ * a negative dentry (ala lookup_one_len). As we know
6062+ * there was no inode for this name before (-ENOENT), then
6063+ * it's safe to call lookup_one_len (which doesn't take a
6064+ * vfsmount).
6065+ */
6066+ dentry = lookup_one_len(name, base, strlen(name));
6067+ if (new_mnt)
6068+ *new_mnt = mntget(lower_nd.path.mnt);
6069+ break;
6070+ default: /* all other real errors */
6071+ dentry = ERR_PTR(err);
6072+ break;
6073+ }
6074+
6075+ return dentry;
6076+}
6077+
6078+/*
6079+ * This is a utility function that fills in a unionfs dentry.
6080+ * Caller must lock this dentry with unionfs_lock_dentry.
6081+ *
6082+ * Returns: 0 (ok), or -ERRNO if an error occurred.
6083+ * XXX: get rid of _partial_lookup and make callers call _lookup_full directly
6084+ */
6085+int unionfs_partial_lookup(struct dentry *dentry)
6086+{
6087+ struct dentry *tmp;
6088+ struct nameidata nd = { .flags = 0 };
6089+ int err = -ENOSYS;
6090+
6091+ tmp = unionfs_lookup_full(dentry, &nd, INTERPOSE_PARTIAL);
6092+
6093+ if (!tmp) {
6094+ err = 0;
6095+ goto out;
6096+ }
6097+ if (IS_ERR(tmp)) {
6098+ err = PTR_ERR(tmp);
6099+ goto out;
6100+ }
6101+ /* XXX: need to change the interface */
6102+ BUG_ON(tmp != dentry);
6103+out:
6104+ return err;
6105+}
6106+
6107+/* The dentry cache is just so we have properly sized dentries. */
6108+static struct kmem_cache *unionfs_dentry_cachep;
6109+int unionfs_init_dentry_cache(void)
6110+{
6111+ unionfs_dentry_cachep =
6112+ kmem_cache_create("unionfs_dentry",
6113+ sizeof(struct unionfs_dentry_info),
6114+ 0, SLAB_RECLAIM_ACCOUNT, NULL);
6115+
6116+ return (unionfs_dentry_cachep ? 0 : -ENOMEM);
6117+}
6118+
6119+void unionfs_destroy_dentry_cache(void)
6120+{
6121+ if (unionfs_dentry_cachep)
6122+ kmem_cache_destroy(unionfs_dentry_cachep);
6123+}
6124+
6125+void free_dentry_private_data(struct dentry *dentry)
6126+{
6127+ if (!dentry || !dentry->d_fsdata)
6128+ return;
6129+ kfree(UNIONFS_D(dentry)->lower_paths);
6130+ UNIONFS_D(dentry)->lower_paths = NULL;
6131+ kmem_cache_free(unionfs_dentry_cachep, dentry->d_fsdata);
6132+ dentry->d_fsdata = NULL;
6133+}
6134+
6135+static inline int __realloc_dentry_private_data(struct dentry *dentry)
6136+{
6137+ struct unionfs_dentry_info *info = UNIONFS_D(dentry);
6138+ void *p;
6139+ int size;
6140+
6141+ BUG_ON(!info);
6142+
6143+ size = sizeof(struct path) * sbmax(dentry->d_sb);
6144+ p = krealloc(info->lower_paths, size, GFP_ATOMIC);
6145+ if (unlikely(!p))
6146+ return -ENOMEM;
6147+
6148+ info->lower_paths = p;
6149+
6150+ info->bstart = -1;
6151+ info->bend = -1;
6152+ info->bopaque = -1;
6153+ info->bcount = sbmax(dentry->d_sb);
6154+ atomic_set(&info->generation,
6155+ atomic_read(&UNIONFS_SB(dentry->d_sb)->generation));
6156+
6157+ memset(info->lower_paths, 0, size);
6158+
6159+ return 0;
6160+}
6161+
6162+/* UNIONFS_D(dentry)->lock must be locked */
6163+int realloc_dentry_private_data(struct dentry *dentry)
6164+{
6165+ if (!__realloc_dentry_private_data(dentry))
6166+ return 0;
6167+
6168+ kfree(UNIONFS_D(dentry)->lower_paths);
6169+ free_dentry_private_data(dentry);
6170+ return -ENOMEM;
6171+}
6172+
6173+/* allocate new dentry private data */
6174+int new_dentry_private_data(struct dentry *dentry, int subclass)
6175+{
6176+ struct unionfs_dentry_info *info = UNIONFS_D(dentry);
6177+
6178+ BUG_ON(info);
6179+
6180+ info = kmem_cache_alloc(unionfs_dentry_cachep, GFP_ATOMIC);
6181+ if (unlikely(!info))
6182+ return -ENOMEM;
6183+
6184+ mutex_init(&info->lock);
6185+ mutex_lock_nested(&info->lock, subclass);
6186+
6187+ info->lower_paths = NULL;
6188+
6189+ dentry->d_fsdata = info;
6190+
6191+ if (!__realloc_dentry_private_data(dentry))
6192+ return 0;
6193+
6194+ mutex_unlock(&info->lock);
6195+ free_dentry_private_data(dentry);
6196+ return -ENOMEM;
6197+}
6198+
6199+/*
6200+ * scan through the lower dentry objects, and set bstart to reflect the
6201+ * starting branch
6202+ */
6203+void update_bstart(struct dentry *dentry)
6204+{
6205+ int bindex;
6206+ int bstart = dbstart(dentry);
6207+ int bend = dbend(dentry);
6208+ struct dentry *lower_dentry;
6209+
6210+ for (bindex = bstart; bindex <= bend; bindex++) {
6211+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
6212+ if (!lower_dentry)
6213+ continue;
6214+ if (lower_dentry->d_inode) {
6215+ dbstart(dentry) = bindex;
6216+ break;
6217+ }
6218+ dput(lower_dentry);
6219+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
6220+ }
6221+}
6222+
6223+
6224+/*
6225+ * Initialize a nameidata structure (the intent part) we can pass to a lower
6226+ * file system. Returns 0 on success or -error (only -ENOMEM possible).
6227+ * Inside that nd structure, this function may also return an allocated
6228+ * struct file (for open intents). The caller, when done with this nd, must
6229+ * kfree the intent file (using release_lower_nd).
6230+ *
6231+ * XXX: this code, and the callers of this code, should be redone using
6232+ * vfs_path_lookup() when (1) the nameidata structure is refactored into a
6233+ * separate intent-structure, and (2) open_namei() is broken into a VFS-only
6234+ * function and a method that other file systems can call.
6235+ */
6236+int init_lower_nd(struct nameidata *nd, unsigned int flags)
6237+{
6238+ int err = 0;
6239+#ifdef ALLOC_LOWER_ND_FILE
6240+ /*
6241+ * XXX: one day we may need to have the lower return an open file
6242+ * for us. It is not needed in 2.6.23-rc1 for nfs2/nfs3, but may
6243+ * very well be needed for nfs4.
6244+ */
6245+ struct file *file;
6246+#endif /* ALLOC_LOWER_ND_FILE */
6247+
6248+ memset(nd, 0, sizeof(struct nameidata));
6249+ if (!flags)
6250+ return err;
6251+
6252+ switch (flags) {
6253+ case LOOKUP_CREATE:
6254+ nd->intent.open.flags |= O_CREAT;
6255+ /* fall through: shared code for create/open cases */
6256+ case LOOKUP_OPEN:
6257+ nd->flags = flags;
6258+ nd->intent.open.flags |= (FMODE_READ | FMODE_WRITE);
6259+#ifdef ALLOC_LOWER_ND_FILE
6260+ file = kzalloc(sizeof(struct file), GFP_KERNEL);
6261+ if (unlikely(!file)) {
6262+ err = -ENOMEM;
6263+ break; /* exit switch statement and thus return */
6264+ }
6265+ nd->intent.open.file = file;
6266+#endif /* ALLOC_LOWER_ND_FILE */
6267+ break;
6268+ default:
6269+ /*
6270+ * We should never get here, for now.
6271+ * We can add new cases here later on.
6272+ */
6273+ pr_debug("unionfs: unknown nameidata flag 0x%x\n", flags);
6274+ BUG();
6275+ break;
6276+ }
6277+
6278+ return err;
6279+}
6280+
6281+void release_lower_nd(struct nameidata *nd, int err)
6282+{
6283+ if (!nd->intent.open.file)
6284+ return;
6285+ else if (!err)
6286+ release_open_intent(nd);
6287+#ifdef ALLOC_LOWER_ND_FILE
6288+ kfree(nd->intent.open.file);
6289+#endif /* ALLOC_LOWER_ND_FILE */
6290+}
6291+
6292+/*
6293+ * Main (and complex) driver function for Unionfs's lookup
6294+ *
6295+ * Returns: NULL (ok), ERR_PTR if an error occurred, or a non-null non-error
6296+ * PTR if d_splice returned a different dentry.
6297+ *
6298+ * If lookupmode is INTERPOSE_PARTIAL/REVAL/REVAL_NEG, the passed dentry's
6299+ * inode info must be locked. If lookupmode is INTERPOSE_LOOKUP (i.e., a
6300+ * newly looked-up dentry), then unionfs_lookup_backend will return a locked
6301+ * dentry's info, which the caller must unlock.
6302+ */
6303+struct dentry *unionfs_lookup_full(struct dentry *dentry,
6304+ struct nameidata *nd_unused, int lookupmode)
6305+{
6306+ int err = 0;
6307+ struct dentry *lower_dentry = NULL;
6308+ struct vfsmount *lower_mnt;
6309+ struct vfsmount *lower_dir_mnt;
6310+ struct dentry *wh_lower_dentry = NULL;
6311+ struct dentry *lower_dir_dentry = NULL;
6312+ struct dentry *parent_dentry = NULL;
6313+ struct dentry *d_interposed = NULL;
6314+ int bindex, bstart, bend, bopaque;
6315+ int opaque, num_positive = 0;
6316+ const char *name;
6317+ int namelen;
6318+ int pos_start, pos_end;
6319+
6320+ /*
6321+ * We should already have a lock on this dentry in the case of a
6322+ * partial lookup, or a revalidation. Otherwise it is returned from
6323+ * new_dentry_private_data already locked.
6324+ */
6325+ verify_locked(dentry);
6326+
6327+ /* must initialize dentry operations */
6328+ dentry->d_op = &unionfs_dops;
6329+
6330+ /* We never partial lookup the root directory. */
6331+ if (IS_ROOT(dentry))
6332+ goto out;
6333+ parent_dentry = dget_parent(dentry);
6334+
6335+ name = dentry->d_name.name;
6336+ namelen = dentry->d_name.len;
6337+
6338+ /* No dentries should get created for possible whiteout names. */
6339+ if (!is_validname(name)) {
6340+ err = -EPERM;
6341+ goto out_free;
6342+ }
6343+
6344+ /* Now start the actual lookup procedure. */
6345+ bstart = dbstart(parent_dentry);
6346+ bend = dbend(parent_dentry);
6347+ bopaque = dbopaque(parent_dentry);
6348+ BUG_ON(bstart < 0);
6349+
6350+ /* adjust bend to bopaque if needed */
6351+ if ((bopaque >= 0) && (bopaque < bend))
6352+ bend = bopaque;
6353+
6354+ /* lookup all possible dentries */
6355+ for (bindex = bstart; bindex <= bend; bindex++) {
6356+
6357+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
6358+ lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
6359+
6360+ /* skip if we already have a positive lower dentry */
6361+ if (lower_dentry) {
6362+ if (dbstart(dentry) < 0)
6363+ dbstart(dentry) = bindex;
6364+ if (bindex > dbend(dentry))
6365+ dbend(dentry) = bindex;
6366+ if (lower_dentry->d_inode)
6367+ num_positive++;
6368+ continue;
6369+ }
6370+
6371+ lower_dir_dentry =
6372+ unionfs_lower_dentry_idx(parent_dentry, bindex);
6373+ /* if the lower dentry's parent does not exist, skip this */
6374+ if (!lower_dir_dentry || !lower_dir_dentry->d_inode)
6375+ continue;
6376+
6377+ /* also skip it if the parent isn't a directory. */
6378+ if (!S_ISDIR(lower_dir_dentry->d_inode->i_mode))
6379+ continue; /* XXX: should be BUG_ON */
6380+
6381+ /* check for whiteouts: stop lookup if found */
6382+ wh_lower_dentry = lookup_whiteout(name, lower_dir_dentry);
6383+ if (IS_ERR(wh_lower_dentry)) {
6384+ err = PTR_ERR(wh_lower_dentry);
6385+ goto out_free;
6386+ }
6387+ if (wh_lower_dentry->d_inode) {
6388+ dbend(dentry) = dbopaque(dentry) = bindex;
6389+ if (dbstart(dentry) < 0)
6390+ dbstart(dentry) = bindex;
6391+ dput(wh_lower_dentry);
6392+ break;
6393+ }
6394+ dput(wh_lower_dentry);
6395+
6396+ /* Now do regular lookup; lookup @name */
6397+ lower_dir_mnt = unionfs_lower_mnt_idx(parent_dentry, bindex);
6398+ lower_mnt = NULL; /* XXX: needed? */
6399+
6400+ lower_dentry = __lookup_one(lower_dir_dentry, lower_dir_mnt,
6401+ name, &lower_mnt);
6402+
6403+ if (IS_ERR(lower_dentry)) {
6404+ err = PTR_ERR(lower_dentry);
6405+ goto out_free;
6406+ }
6407+ unionfs_set_lower_dentry_idx(dentry, bindex, lower_dentry);
6408+ BUG_ON(!lower_mnt);
6409+ unionfs_set_lower_mnt_idx(dentry, bindex, lower_mnt);
6410+
6411+ /* adjust dbstart/end */
6412+ if (dbstart(dentry) < 0)
6413+ dbstart(dentry) = bindex;
6414+ if (bindex > dbend(dentry))
6415+ dbend(dentry) = bindex;
6416+ /*
6417+ * We always store the lower dentries above, and update
6418+ * dbstart/dbend, even if the whole unionfs dentry is
6419+ * negative (i.e., no lower inodes).
6420+ */
6421+ if (!lower_dentry->d_inode)
6422+ continue;
6423+ num_positive++;
6424+
6425+ /*
6426+ * check if we just found an opaque directory, if so, stop
6427+ * lookups here.
6428+ */
6429+ if (!S_ISDIR(lower_dentry->d_inode->i_mode))
6430+ continue;
6431+ opaque = is_opaque_dir(dentry, bindex);
6432+ if (opaque < 0) {
6433+ err = opaque;
6434+ goto out_free;
6435+ } else if (opaque) {
6436+ dbend(dentry) = dbopaque(dentry) = bindex;
6437+ break;
6438+ }
6439+ dbend(dentry) = bindex;
6440+
6441+ /* update parent directory's atime with the bindex */
6442+ fsstack_copy_attr_atime(parent_dentry->d_inode,
6443+ lower_dir_dentry->d_inode);
6444+ }
6445+
6446+ /* sanity checks, then decide if to process a negative dentry */
6447+ BUG_ON(dbstart(dentry) < 0 && dbend(dentry) >= 0);
6448+ BUG_ON(dbstart(dentry) >= 0 && dbend(dentry) < 0);
6449+
6450+ if (num_positive > 0)
6451+ goto out_positive;
6452+
6453+ /*** handle NEGATIVE dentries ***/
6454+
6455+ /*
6456+ * If negative, keep only first lower negative dentry, to save on
6457+ * memory.
6458+ */
6459+ if (dbstart(dentry) < dbend(dentry)) {
6460+ path_put_lowers(dentry, dbstart(dentry) + 1,
6461+ dbend(dentry), false);
6462+ dbend(dentry) = dbstart(dentry);
6463+ }
6464+ if (lookupmode == INTERPOSE_PARTIAL)
6465+ goto out;
6466+ if (lookupmode == INTERPOSE_LOOKUP) {
6467+ /*
6468+ * If all we found was a whiteout in the first available
6469+ * branch, then create a negative dentry for a possibly new
6470+ * file to be created.
6471+ */
6472+ if (dbopaque(dentry) < 0)
6473+ goto out;
6474+ /* XXX: need to get mnt here */
6475+ bindex = dbstart(dentry);
6476+ if (unionfs_lower_dentry_idx(dentry, bindex))
6477+ goto out;
6478+ lower_dir_dentry =
6479+ unionfs_lower_dentry_idx(parent_dentry, bindex);
6480+ if (!lower_dir_dentry || !lower_dir_dentry->d_inode)
6481+ goto out;
6482+ if (!S_ISDIR(lower_dir_dentry->d_inode->i_mode))
6483+ goto out; /* XXX: should be BUG_ON */
6484+ /* XXX: do we need to cross bind mounts here? */
6485+ lower_dentry = lookup_one_len(name, lower_dir_dentry, namelen);
6486+ if (IS_ERR(lower_dentry)) {
6487+ err = PTR_ERR(lower_dentry);
6488+ goto out;
6489+ }
6490+ /* XXX: need to mntget/mntput as needed too! */
6491+ unionfs_set_lower_dentry_idx(dentry, bindex, lower_dentry);
6492+ /* XXX: wrong mnt for crossing bind mounts! */
6493+ lower_mnt = unionfs_mntget(dentry->d_sb->s_root, bindex);
6494+ unionfs_set_lower_mnt_idx(dentry, bindex, lower_mnt);
6495+
6496+ goto out;
6497+ }
6498+
6499+ /* if we're revalidating a positive dentry, don't make it negative */
6500+ if (lookupmode != INTERPOSE_REVAL)
6501+ d_add(dentry, NULL);
6502+
6503+ goto out;
6504+
6505+out_positive:
6506+ /*** handle POSITIVE dentries ***/
6507+
6508+ /*
6509+ * This unionfs dentry is positive (at least one lower inode
6510+ * exists), so scan entire dentry from beginning to end, and remove
6511+ * any negative lower dentries, if any. Then, update dbstart/dbend
6512+ * to reflect the start/end of positive dentries.
6513+ */
6514+ pos_start = pos_end = -1;
6515+ for (bindex = bstart; bindex <= bend; bindex++) {
6516+ lower_dentry = unionfs_lower_dentry_idx(dentry,
6517+ bindex);
6518+ if (lower_dentry && lower_dentry->d_inode) {
6519+ if (pos_start < 0)
6520+ pos_start = bindex;
6521+ if (bindex > pos_end)
6522+ pos_end = bindex;
6523+ continue;
6524+ }
6525+ path_put_lowers(dentry, bindex, bindex, false);
6526+ }
6527+ if (pos_start >= 0)
6528+ dbstart(dentry) = pos_start;
6529+ if (pos_end >= 0)
6530+ dbend(dentry) = pos_end;
6531+
6532+ /* Partial lookups need to re-interpose, or throw away older negs. */
6533+ if (lookupmode == INTERPOSE_PARTIAL) {
6534+ if (dentry->d_inode) {
6535+ unionfs_reinterpose(dentry);
6536+ goto out;
6537+ }
6538+
6539+ /*
6540+ * This dentry was positive, so it is as if we had a
6541+ * negative revalidation.
6542+ */
6543+ lookupmode = INTERPOSE_REVAL_NEG;
6544+ update_bstart(dentry);
6545+ }
6546+
6547+ /*
6548+ * Interpose can return a dentry if d_splice returned a different
6549+ * dentry.
6550+ */
6551+ d_interposed = unionfs_interpose(dentry, dentry->d_sb, lookupmode);
6552+ if (IS_ERR(d_interposed))
6553+ err = PTR_ERR(d_interposed);
6554+ else if (d_interposed)
6555+ dentry = d_interposed;
6556+
6557+ if (!err)
6558+ goto out;
6559+ d_drop(dentry);
6560+
6561+out_free:
6562+ /* should dput/mntput all the underlying dentries on error condition */
6563+ if (dbstart(dentry) >= 0)
6564+ path_put_lowers_all(dentry, false);
6565+ /* free lower_paths unconditionally */
6566+ kfree(UNIONFS_D(dentry)->lower_paths);
6567+ UNIONFS_D(dentry)->lower_paths = NULL;
6568+
6569+out:
6570+ if (dentry && UNIONFS_D(dentry)) {
6571+ BUG_ON(dbstart(dentry) < 0 && dbend(dentry) >= 0);
6572+ BUG_ON(dbstart(dentry) >= 0 && dbend(dentry) < 0);
6573+ }
6574+ if (d_interposed && UNIONFS_D(d_interposed)) {
6575+ BUG_ON(dbstart(d_interposed) < 0 && dbend(d_interposed) >= 0);
6576+ BUG_ON(dbstart(d_interposed) >= 0 && dbend(d_interposed) < 0);
6577+ }
6578+
6579+ dput(parent_dentry);
6580+ if (!err && d_interposed)
6581+ return d_interposed;
6582+ return ERR_PTR(err);
6583+}
6584diff --git a/fs/unionfs/main.c b/fs/unionfs/main.c
6585new file mode 100644
6586index 0000000..fea670b
6587--- /dev/null
6588+++ b/fs/unionfs/main.c
6589@@ -0,0 +1,777 @@
6590+/*
6591+ * Copyright (c) 2003-2008 Erez Zadok
6592+ * Copyright (c) 2003-2006 Charles P. Wright
6593+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
6594+ * Copyright (c) 2005-2006 Junjiro Okajima
6595+ * Copyright (c) 2005 Arun M. Krishnakumar
6596+ * Copyright (c) 2004-2006 David P. Quigley
6597+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
6598+ * Copyright (c) 2003 Puja Gupta
6599+ * Copyright (c) 2003 Harikesavan Krishnan
6600+ * Copyright (c) 2003-2008 Stony Brook University
6601+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
6602+ *
6603+ * This program is free software; you can redistribute it and/or modify
6604+ * it under the terms of the GNU General Public License version 2 as
6605+ * published by the Free Software Foundation.
6606+ */
6607+
6608+#include "union.h"
6609+#include <linux/module.h>
6610+#include <linux/moduleparam.h>
6611+
6612+static void unionfs_fill_inode(struct dentry *dentry,
6613+ struct inode *inode)
6614+{
6615+ struct inode *lower_inode;
6616+ struct dentry *lower_dentry;
6617+ int bindex, bstart, bend;
6618+
6619+ bstart = dbstart(dentry);
6620+ bend = dbend(dentry);
6621+
6622+ for (bindex = bstart; bindex <= bend; bindex++) {
6623+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
6624+ if (!lower_dentry) {
6625+ unionfs_set_lower_inode_idx(inode, bindex, NULL);
6626+ continue;
6627+ }
6628+
6629+ /* Initialize the lower inode to the new lower inode. */
6630+ if (!lower_dentry->d_inode)
6631+ continue;
6632+
6633+ unionfs_set_lower_inode_idx(inode, bindex,
6634+ igrab(lower_dentry->d_inode));
6635+ }
6636+
6637+ ibstart(inode) = dbstart(dentry);
6638+ ibend(inode) = dbend(dentry);
6639+
6640+ /* Use attributes from the first branch. */
6641+ lower_inode = unionfs_lower_inode(inode);
6642+
6643+ /* Use different set of inode ops for symlinks & directories */
6644+ if (S_ISLNK(lower_inode->i_mode))
6645+ inode->i_op = &unionfs_symlink_iops;
6646+ else if (S_ISDIR(lower_inode->i_mode))
6647+ inode->i_op = &unionfs_dir_iops;
6648+
6649+ /* Use different set of file ops for directories */
6650+ if (S_ISDIR(lower_inode->i_mode))
6651+ inode->i_fop = &unionfs_dir_fops;
6652+
6653+ /* properly initialize special inodes */
6654+ if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) ||
6655+ S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode))
6656+ init_special_inode(inode, lower_inode->i_mode,
6657+ lower_inode->i_rdev);
6658+
6659+ /* all well, copy inode attributes */
6660+ unionfs_copy_attr_all(inode, lower_inode);
6661+ fsstack_copy_inode_size(inode, lower_inode);
6662+}
6663+
6664+/*
6665+ * Connect a unionfs inode dentry/inode with several lower ones. This is
6666+ * the classic stackable file system "vnode interposition" action.
6667+ *
6668+ * @sb: unionfs's super_block
6669+ */
6670+struct dentry *unionfs_interpose(struct dentry *dentry, struct super_block *sb,
6671+ int flag)
6672+{
6673+ int err = 0;
6674+ struct inode *inode;
6675+ int need_fill_inode = 1;
6676+ struct dentry *spliced = NULL;
6677+
6678+ verify_locked(dentry);
6679+
6680+ /*
6681+ * We allocate our new inode below by calling unionfs_iget,
6682+ * which will initialize some of the new inode's fields
6683+ */
6684+
6685+ /*
6686+ * On revalidate we've already got our own inode and just need
6687+ * to fix it up.
6688+ */
6689+ if (flag == INTERPOSE_REVAL) {
6690+ inode = dentry->d_inode;
6691+ UNIONFS_I(inode)->bstart = -1;
6692+ UNIONFS_I(inode)->bend = -1;
6693+ atomic_set(&UNIONFS_I(inode)->generation,
6694+ atomic_read(&UNIONFS_SB(sb)->generation));
6695+
6696+ UNIONFS_I(inode)->lower_inodes =
6697+ kcalloc(sbmax(sb), sizeof(struct inode *), GFP_KERNEL);
6698+ if (unlikely(!UNIONFS_I(inode)->lower_inodes)) {
6699+ err = -ENOMEM;
6700+ goto out;
6701+ }
6702+ } else {
6703+ /* get unique inode number for unionfs */
6704+ inode = unionfs_iget(sb, iunique(sb, UNIONFS_ROOT_INO));
6705+ if (IS_ERR(inode)) {
6706+ err = PTR_ERR(inode);
6707+ goto out;
6708+ }
6709+ if (atomic_read(&inode->i_count) > 1)
6710+ goto skip;
6711+ }
6712+
6713+ need_fill_inode = 0;
6714+ unionfs_fill_inode(dentry, inode);
6715+
6716+skip:
6717+ /* only (our) lookup wants to do a d_add */
6718+ switch (flag) {
6719+ case INTERPOSE_DEFAULT:
6720+ /* for operations which create new inodes */
6721+ d_add(dentry, inode);
6722+ break;
6723+ case INTERPOSE_REVAL_NEG:
6724+ d_instantiate(dentry, inode);
6725+ break;
6726+ case INTERPOSE_LOOKUP:
6727+ spliced = d_splice_alias(inode, dentry);
6728+ if (spliced && spliced != dentry) {
6729+ /*
6730+ * d_splice can return a dentry if it was
6731+ * disconnected and had to be moved. We must ensure
6732+ * that the private data of the new dentry is
6733+ * correct and that the inode info was filled
6734+ * properly. Finally we must return this new
6735+ * dentry.
6736+ */
6737+ spliced->d_op = &unionfs_dops;
6738+ spliced->d_fsdata = dentry->d_fsdata;
6739+ dentry->d_fsdata = NULL;
6740+ dentry = spliced;
6741+ if (need_fill_inode) {
6742+ need_fill_inode = 0;
6743+ unionfs_fill_inode(dentry, inode);
6744+ }
6745+ goto out_spliced;
6746+ } else if (!spliced) {
6747+ if (need_fill_inode) {
6748+ need_fill_inode = 0;
6749+ unionfs_fill_inode(dentry, inode);
6750+ goto out_spliced;
6751+ }
6752+ }
6753+ break;
6754+ case INTERPOSE_REVAL:
6755+ /* Do nothing. */
6756+ break;
6757+ default:
6758+ printk(KERN_CRIT "unionfs: invalid interpose flag passed!\n");
6759+ BUG();
6760+ }
6761+ goto out;
6762+
6763+out_spliced:
6764+ if (!err)
6765+ return spliced;
6766+out:
6767+ return ERR_PTR(err);
6768+}
6769+
6770+/* like interpose above, but for an already existing dentry */
6771+void unionfs_reinterpose(struct dentry *dentry)
6772+{
6773+ struct dentry *lower_dentry;
6774+ struct inode *inode;
6775+ int bindex, bstart, bend;
6776+
6777+ verify_locked(dentry);
6778+
6779+ /* This is pre-allocated inode */
6780+ inode = dentry->d_inode;
6781+
6782+ bstart = dbstart(dentry);
6783+ bend = dbend(dentry);
6784+ for (bindex = bstart; bindex <= bend; bindex++) {
6785+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
6786+ if (!lower_dentry)
6787+ continue;
6788+
6789+ if (!lower_dentry->d_inode)
6790+ continue;
6791+ if (unionfs_lower_inode_idx(inode, bindex))
6792+ continue;
6793+ unionfs_set_lower_inode_idx(inode, bindex,
6794+ igrab(lower_dentry->d_inode));
6795+ }
6796+ ibstart(inode) = dbstart(dentry);
6797+ ibend(inode) = dbend(dentry);
6798+}
6799+
6800+/*
6801+ * make sure the branch we just looked up (nd) makes sense:
6802+ *
6803+ * 1) we're not trying to stack unionfs on top of unionfs
6804+ * 2) it exists
6805+ * 3) is a directory
6806+ */
6807+int check_branch(struct nameidata *nd)
6808+{
6809+ /* XXX: remove in ODF code -- stacking unions allowed there */
6810+ if (!strcmp(nd->path.dentry->d_sb->s_type->name, UNIONFS_NAME))
6811+ return -EINVAL;
6812+ if (!nd->path.dentry->d_inode)
6813+ return -ENOENT;
6814+ if (!S_ISDIR(nd->path.dentry->d_inode->i_mode))
6815+ return -ENOTDIR;
6816+ return 0;
6817+}
6818+
6819+/* checks if two lower_dentries have overlapping branches */
6820+static int is_branch_overlap(struct dentry *dent1, struct dentry *dent2)
6821+{
6822+ struct dentry *dent = NULL;
6823+
6824+ dent = dent1;
6825+ while ((dent != dent2) && (dent->d_parent != dent))
6826+ dent = dent->d_parent;
6827+
6828+ if (dent == dent2)
6829+ return 1;
6830+
6831+ dent = dent2;
6832+ while ((dent != dent1) && (dent->d_parent != dent))
6833+ dent = dent->d_parent;
6834+
6835+ return (dent == dent1);
6836+}
6837+
6838+/*
6839+ * Parse "ro" or "rw" options, but default to "rw" if no mode options was
6840+ * specified. Fill the mode bits in @perms. If encounter an unknown
6841+ * string, return -EINVAL. Otherwise return 0.
6842+ */
6843+int parse_branch_mode(const char *name, int *perms)
6844+{
6845+ if (!name || !strcmp(name, "rw")) {
6846+ *perms = MAY_READ | MAY_WRITE;
6847+ return 0;
6848+ }
6849+ if (!strcmp(name, "ro")) {
6850+ *perms = MAY_READ;
6851+ return 0;
6852+ }
6853+ return -EINVAL;
6854+}
6855+
6856+/*
6857+ * parse the dirs= mount argument
6858+ *
6859+ * We don't need to lock the superblock private data's rwsem, as we get
6860+ * called only by unionfs_read_super - it is still a long time before anyone
6861+ * can even get a reference to us.
6862+ */
6863+static int parse_dirs_option(struct super_block *sb, struct unionfs_dentry_info
6864+ *lower_root_info, char *options)
6865+{
6866+ struct nameidata nd;
6867+ char *name;
6868+ int err = 0;
6869+ int branches = 1;
6870+ int bindex = 0;
6871+ int i = 0;
6872+ int j = 0;
6873+ struct dentry *dent1;
6874+ struct dentry *dent2;
6875+
6876+ if (options[0] == '\0') {
6877+ printk(KERN_ERR "unionfs: no branches specified\n");
6878+ err = -EINVAL;
6879+ goto out;
6880+ }
6881+
6882+ /*
6883+ * Each colon means we have a separator, this is really just a rough
6884+ * guess, since strsep will handle empty fields for us.
6885+ */
6886+ for (i = 0; options[i]; i++)
6887+ if (options[i] == ':')
6888+ branches++;
6889+
6890+ /* allocate space for underlying pointers to lower dentry */
6891+ UNIONFS_SB(sb)->data =
6892+ kcalloc(branches, sizeof(struct unionfs_data), GFP_KERNEL);
6893+ if (unlikely(!UNIONFS_SB(sb)->data)) {
6894+ err = -ENOMEM;
6895+ goto out;
6896+ }
6897+
6898+ lower_root_info->lower_paths =
6899+ kcalloc(branches, sizeof(struct path), GFP_KERNEL);
6900+ if (unlikely(!lower_root_info->lower_paths)) {
6901+ err = -ENOMEM;
6902+ goto out;
6903+ }
6904+
6905+ /* now parsing a string such as "b1:b2=rw:b3=ro:b4" */
6906+ branches = 0;
6907+ while ((name = strsep(&options, ":")) != NULL) {
6908+ int perms;
6909+ char *mode = strchr(name, '=');
6910+
6911+ if (!name)
6912+ continue;
6913+ if (!*name) { /* bad use of ':' (extra colons) */
6914+ err = -EINVAL;
6915+ goto out;
6916+ }
6917+
6918+ branches++;
6919+
6920+ /* strip off '=' if any */
6921+ if (mode)
6922+ *mode++ = '\0';
6923+
6924+ err = parse_branch_mode(mode, &perms);
6925+ if (err) {
6926+ printk(KERN_ERR "unionfs: invalid mode \"%s\" for "
6927+ "branch %d\n", mode, bindex);
6928+ goto out;
6929+ }
6930+ /* ensure that leftmost branch is writeable */
6931+ if (!bindex && !(perms & MAY_WRITE)) {
6932+ printk(KERN_ERR "unionfs: leftmost branch cannot be "
6933+ "read-only (use \"-o ro\" to create a "
6934+ "read-only union)\n");
6935+ err = -EINVAL;
6936+ goto out;
6937+ }
6938+
6939+ err = path_lookup(name, LOOKUP_FOLLOW, &nd);
6940+ if (err) {
6941+ printk(KERN_ERR "unionfs: error accessing "
6942+ "lower directory '%s' (error %d)\n",
6943+ name, err);
6944+ goto out;
6945+ }
6946+
6947+ err = check_branch(&nd);
6948+ if (err) {
6949+ printk(KERN_ERR "unionfs: lower directory "
6950+ "'%s' is not a valid branch\n", name);
6951+ path_put(&nd.path);
6952+ goto out;
6953+ }
6954+
6955+ lower_root_info->lower_paths[bindex].dentry = nd.path.dentry;
6956+ lower_root_info->lower_paths[bindex].mnt = nd.path.mnt;
6957+
6958+ set_branchperms(sb, bindex, perms);
6959+ set_branch_count(sb, bindex, 0);
6960+ new_branch_id(sb, bindex);
6961+
6962+ if (lower_root_info->bstart < 0)
6963+ lower_root_info->bstart = bindex;
6964+ lower_root_info->bend = bindex;
6965+ bindex++;
6966+ }
6967+
6968+ if (branches == 0) {
6969+ printk(KERN_ERR "unionfs: no branches specified\n");
6970+ err = -EINVAL;
6971+ goto out;
6972+ }
6973+
6974+ BUG_ON(branches != (lower_root_info->bend + 1));
6975+
6976+ /*
6977+ * Ensure that no overlaps exist in the branches.
6978+ *
6979+ * This test is required because the Linux kernel has no support
6980+ * currently for ensuring coherency between stackable layers and
6981+ * branches. If we were to allow overlapping branches, it would be
6982+ * possible, for example, to delete a file via one branch, which
6983+ * would not be reflected in another branch. Such incoherency could
6984+ * lead to inconsistencies and even kernel oopses. Rather than
6985+ * implement hacks to work around some of these cache-coherency
6986+ * problems, we prevent branch overlapping, for now. A complete
6987+ * solution will involve proper kernel/VFS support for cache
6988+ * coherency, at which time we could safely remove this
6989+ * branch-overlapping test.
6990+ */
6991+ for (i = 0; i < branches; i++) {
6992+ dent1 = lower_root_info->lower_paths[i].dentry;
6993+ for (j = i + 1; j < branches; j++) {
6994+ dent2 = lower_root_info->lower_paths[j].dentry;
6995+ if (is_branch_overlap(dent1, dent2)) {
6996+ printk(KERN_ERR "unionfs: branches %d and "
6997+ "%d overlap\n", i, j);
6998+ err = -EINVAL;
6999+ goto out;
7000+ }
7001+ }
7002+ }
7003+
7004+out:
7005+ if (err) {
7006+ for (i = 0; i < branches; i++)
7007+ if (lower_root_info->lower_paths[i].dentry) {
7008+ dput(lower_root_info->lower_paths[i].dentry);
7009+ /* initialize: can't use unionfs_mntput here */
7010+ mntput(lower_root_info->lower_paths[i].mnt);
7011+ }
7012+
7013+ kfree(lower_root_info->lower_paths);
7014+ kfree(UNIONFS_SB(sb)->data);
7015+
7016+ /*
7017+ * MUST clear the pointers to prevent potential double free if
7018+ * the caller dies later on
7019+ */
7020+ lower_root_info->lower_paths = NULL;
7021+ UNIONFS_SB(sb)->data = NULL;
7022+ }
7023+ return err;
7024+}
7025+
7026+/*
7027+ * Parse mount options. See the manual page for usage instructions.
7028+ *
7029+ * Returns the dentry object of the lower-level (lower) directory;
7030+ * We want to mount our stackable file system on top of that lower directory.
7031+ */
7032+static struct unionfs_dentry_info *unionfs_parse_options(
7033+ struct super_block *sb,
7034+ char *options)
7035+{
7036+ struct unionfs_dentry_info *lower_root_info;
7037+ char *optname;
7038+ int err = 0;
7039+ int bindex;
7040+ int dirsfound = 0;
7041+
7042+ /* allocate private data area */
7043+ err = -ENOMEM;
7044+ lower_root_info =
7045+ kzalloc(sizeof(struct unionfs_dentry_info), GFP_KERNEL);
7046+ if (unlikely(!lower_root_info))
7047+ goto out_error;
7048+ lower_root_info->bstart = -1;
7049+ lower_root_info->bend = -1;
7050+ lower_root_info->bopaque = -1;
7051+
7052+ while ((optname = strsep(&options, ",")) != NULL) {
7053+ char *optarg;
7054+
7055+ if (!optname || !*optname)
7056+ continue;
7057+
7058+ optarg = strchr(optname, '=');
7059+ if (optarg)
7060+ *optarg++ = '\0';
7061+
7062+ /*
7063+ * All of our options take an argument now. Insert ones that
7064+ * don't, above this check.
7065+ */
7066+ if (!optarg) {
7067+ printk(KERN_ERR "unionfs: %s requires an argument\n",
7068+ optname);
7069+ err = -EINVAL;
7070+ goto out_error;
7071+ }
7072+
7073+ if (!strcmp("dirs", optname)) {
7074+ if (++dirsfound > 1) {
7075+ printk(KERN_ERR
7076+ "unionfs: multiple dirs specified\n");
7077+ err = -EINVAL;
7078+ goto out_error;
7079+ }
7080+ err = parse_dirs_option(sb, lower_root_info, optarg);
7081+ if (err)
7082+ goto out_error;
7083+ continue;
7084+ }
7085+
7086+ err = -EINVAL;
7087+ printk(KERN_ERR
7088+ "unionfs: unrecognized option '%s'\n", optname);
7089+ goto out_error;
7090+ }
7091+ if (dirsfound != 1) {
7092+ printk(KERN_ERR "unionfs: dirs option required\n");
7093+ err = -EINVAL;
7094+ goto out_error;
7095+ }
7096+ goto out;
7097+
7098+out_error:
7099+ if (lower_root_info && lower_root_info->lower_paths) {
7100+ for (bindex = lower_root_info->bstart;
7101+ bindex >= 0 && bindex <= lower_root_info->bend;
7102+ bindex++) {
7103+ struct dentry *d;
7104+ struct vfsmount *m;
7105+
7106+ d = lower_root_info->lower_paths[bindex].dentry;
7107+ m = lower_root_info->lower_paths[bindex].mnt;
7108+
7109+ dput(d);
7110+ /* initializing: can't use unionfs_mntput here */
7111+ mntput(m);
7112+ }
7113+ }
7114+
7115+ kfree(lower_root_info->lower_paths);
7116+ kfree(lower_root_info);
7117+
7118+ kfree(UNIONFS_SB(sb)->data);
7119+ UNIONFS_SB(sb)->data = NULL;
7120+
7121+ lower_root_info = ERR_PTR(err);
7122+out:
7123+ return lower_root_info;
7124+}
7125+
7126+/*
7127+ * our custom d_alloc_root work-alike
7128+ *
7129+ * we can't use d_alloc_root if we want to use our own interpose function
7130+ * unchanged, so we simply call our own "fake" d_alloc_root
7131+ */
7132+static struct dentry *unionfs_d_alloc_root(struct super_block *sb)
7133+{
7134+ struct dentry *ret = NULL;
7135+
7136+ if (sb) {
7137+ static const struct qstr name = {
7138+ .name = "/",
7139+ .len = 1
7140+ };
7141+
7142+ ret = d_alloc(NULL, &name);
7143+ if (likely(ret)) {
7144+ ret->d_op = &unionfs_dops;
7145+ ret->d_sb = sb;
7146+ ret->d_parent = ret;
7147+ }
7148+ }
7149+ return ret;
7150+}
7151+
7152+/*
7153+ * There is no need to lock the unionfs_super_info's rwsem as there is no
7154+ * way anyone can have a reference to the superblock at this point in time.
7155+ */
7156+static int unionfs_read_super(struct super_block *sb, void *raw_data,
7157+ int silent)
7158+{
7159+ int err = 0;
7160+ struct unionfs_dentry_info *lower_root_info = NULL;
7161+ int bindex, bstart, bend;
7162+
7163+ if (!raw_data) {
7164+ printk(KERN_ERR
7165+ "unionfs: read_super: missing data argument\n");
7166+ err = -EINVAL;
7167+ goto out;
7168+ }
7169+
7170+ /* Allocate superblock private data */
7171+ sb->s_fs_info = kzalloc(sizeof(struct unionfs_sb_info), GFP_KERNEL);
7172+ if (unlikely(!UNIONFS_SB(sb))) {
7173+ printk(KERN_CRIT "unionfs: read_super: out of memory\n");
7174+ err = -ENOMEM;
7175+ goto out;
7176+ }
7177+
7178+ UNIONFS_SB(sb)->bend = -1;
7179+ atomic_set(&UNIONFS_SB(sb)->generation, 1);
7180+ init_rwsem(&UNIONFS_SB(sb)->rwsem);
7181+ UNIONFS_SB(sb)->high_branch_id = -1; /* -1 == invalid branch ID */
7182+
7183+ lower_root_info = unionfs_parse_options(sb, raw_data);
7184+ if (IS_ERR(lower_root_info)) {
7185+ printk(KERN_ERR
7186+ "unionfs: read_super: error while parsing options "
7187+ "(err = %ld)\n", PTR_ERR(lower_root_info));
7188+ err = PTR_ERR(lower_root_info);
7189+ lower_root_info = NULL;
7190+ goto out_free;
7191+ }
7192+ if (lower_root_info->bstart == -1) {
7193+ err = -ENOENT;
7194+ goto out_free;
7195+ }
7196+
7197+ /* set the lower superblock field of upper superblock */
7198+ bstart = lower_root_info->bstart;
7199+ BUG_ON(bstart != 0);
7200+ sbend(sb) = bend = lower_root_info->bend;
7201+ for (bindex = bstart; bindex <= bend; bindex++) {
7202+ struct dentry *d = lower_root_info->lower_paths[bindex].dentry;
7203+ atomic_inc(&d->d_sb->s_active);
7204+ unionfs_set_lower_super_idx(sb, bindex, d->d_sb);
7205+ }
7206+
7207+ /* max Bytes is the maximum bytes from highest priority branch */
7208+ sb->s_maxbytes = unionfs_lower_super_idx(sb, 0)->s_maxbytes;
7209+
7210+ /*
7211+ * Our c/m/atime granularity is 1 ns because we may stack on file
7212+ * systems whose granularity is as good. This is important for our
7213+ * time-based cache coherency.
7214+ */
7215+ sb->s_time_gran = 1;
7216+
7217+ sb->s_op = &unionfs_sops;
7218+
7219+ /* See comment next to the definition of unionfs_d_alloc_root */
7220+ sb->s_root = unionfs_d_alloc_root(sb);
7221+ if (unlikely(!sb->s_root)) {
7222+ err = -ENOMEM;
7223+ goto out_dput;
7224+ }
7225+
7226+ /* link the upper and lower dentries */
7227+ sb->s_root->d_fsdata = NULL;
7228+ err = new_dentry_private_data(sb->s_root, UNIONFS_DMUTEX_ROOT);
7229+ if (unlikely(err))
7230+ goto out_freedpd;
7231+
7232+ /* Set the lower dentries for s_root */
7233+ for (bindex = bstart; bindex <= bend; bindex++) {
7234+ struct dentry *d;
7235+ struct vfsmount *m;
7236+
7237+ d = lower_root_info->lower_paths[bindex].dentry;
7238+ m = lower_root_info->lower_paths[bindex].mnt;
7239+
7240+ unionfs_set_lower_dentry_idx(sb->s_root, bindex, d);
7241+ unionfs_set_lower_mnt_idx(sb->s_root, bindex, m);
7242+ }
7243+ dbstart(sb->s_root) = bstart;
7244+ dbend(sb->s_root) = bend;
7245+
7246+ /* Set the generation number to one, since this is for the mount. */
7247+ atomic_set(&UNIONFS_D(sb->s_root)->generation, 1);
7248+
7249+ /*
7250+ * Call interpose to create the upper level inode. Only
7251+ * INTERPOSE_LOOKUP can return a value other than 0 on err.
7252+ */
7253+ err = PTR_ERR(unionfs_interpose(sb->s_root, sb, 0));
7254+ unionfs_unlock_dentry(sb->s_root);
7255+ if (!err)
7256+ goto out;
7257+ /* else fall through */
7258+
7259+out_freedpd:
7260+ if (UNIONFS_D(sb->s_root)) {
7261+ kfree(UNIONFS_D(sb->s_root)->lower_paths);
7262+ free_dentry_private_data(sb->s_root);
7263+ }
7264+ dput(sb->s_root);
7265+
7266+out_dput:
7267+ if (lower_root_info && !IS_ERR(lower_root_info)) {
7268+ for (bindex = lower_root_info->bstart;
7269+ bindex <= lower_root_info->bend; bindex++) {
7270+ struct dentry *d;
7271+ struct vfsmount *m;
7272+
7273+ d = lower_root_info->lower_paths[bindex].dentry;
7274+ m = lower_root_info->lower_paths[bindex].mnt;
7275+
7276+ dput(d);
7277+ /* initializing: can't use unionfs_mntput here */
7278+ mntput(m);
7279+ /* drop refs we took earlier */
7280+ atomic_dec(&d->d_sb->s_active);
7281+ }
7282+ kfree(lower_root_info->lower_paths);
7283+ kfree(lower_root_info);
7284+ lower_root_info = NULL;
7285+ }
7286+
7287+out_free:
7288+ kfree(UNIONFS_SB(sb)->data);
7289+ kfree(UNIONFS_SB(sb));
7290+ sb->s_fs_info = NULL;
7291+
7292+out:
7293+ if (lower_root_info && !IS_ERR(lower_root_info)) {
7294+ kfree(lower_root_info->lower_paths);
7295+ kfree(lower_root_info);
7296+ }
7297+ return err;
7298+}
7299+
7300+static int unionfs_get_sb(struct file_system_type *fs_type,
7301+ int flags, const char *dev_name,
7302+ void *raw_data, struct vfsmount *mnt)
7303+{
7304+ int err;
7305+ err = get_sb_nodev(fs_type, flags, raw_data, unionfs_read_super, mnt);
7306+ if (!err)
7307+ UNIONFS_SB(mnt->mnt_sb)->dev_name =
7308+ kstrdup(dev_name, GFP_KERNEL);
7309+ return err;
7310+}
7311+
7312+static struct file_system_type unionfs_fs_type = {
7313+ .owner = THIS_MODULE,
7314+ .name = UNIONFS_NAME,
7315+ .get_sb = unionfs_get_sb,
7316+ .kill_sb = generic_shutdown_super,
7317+ .fs_flags = FS_REVAL_DOT,
7318+};
7319+
7320+static int __init init_unionfs_fs(void)
7321+{
7322+ int err;
7323+
7324+ pr_info("Registering unionfs " UNIONFS_VERSION "\n");
7325+
7326+ err = unionfs_init_filldir_cache();
7327+ if (unlikely(err))
7328+ goto out;
7329+ err = unionfs_init_inode_cache();
7330+ if (unlikely(err))
7331+ goto out;
7332+ err = unionfs_init_dentry_cache();
7333+ if (unlikely(err))
7334+ goto out;
7335+ err = init_sioq();
7336+ if (unlikely(err))
7337+ goto out;
7338+ err = register_filesystem(&unionfs_fs_type);
7339+out:
7340+ if (unlikely(err)) {
7341+ stop_sioq();
7342+ unionfs_destroy_filldir_cache();
7343+ unionfs_destroy_inode_cache();
7344+ unionfs_destroy_dentry_cache();
7345+ }
7346+ return err;
7347+}
7348+
7349+static void __exit exit_unionfs_fs(void)
7350+{
7351+ stop_sioq();
7352+ unionfs_destroy_filldir_cache();
7353+ unionfs_destroy_inode_cache();
7354+ unionfs_destroy_dentry_cache();
7355+ unregister_filesystem(&unionfs_fs_type);
7356+ pr_info("Completed unionfs module unload\n");
7357+}
7358+
7359+MODULE_AUTHOR("Erez Zadok, Filesystems and Storage Lab, Stony Brook University"
7360+ " (http://www.fsl.cs.sunysb.edu)");
7361+MODULE_DESCRIPTION("Unionfs " UNIONFS_VERSION
7362+ " (http://unionfs.filesystems.org)");
7363+MODULE_LICENSE("GPL");
7364+
7365+module_init(init_unionfs_fs);
7366+module_exit(exit_unionfs_fs);
7367diff --git a/fs/unionfs/mmap.c b/fs/unionfs/mmap.c
7368new file mode 100644
7369index 0000000..b7d4713
7370--- /dev/null
7371+++ b/fs/unionfs/mmap.c
7372@@ -0,0 +1,89 @@
7373+/*
7374+ * Copyright (c) 2003-2008 Erez Zadok
7375+ * Copyright (c) 2003-2006 Charles P. Wright
7376+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
7377+ * Copyright (c) 2005-2006 Junjiro Okajima
7378+ * Copyright (c) 2006 Shaya Potter
7379+ * Copyright (c) 2005 Arun M. Krishnakumar
7380+ * Copyright (c) 2004-2006 David P. Quigley
7381+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
7382+ * Copyright (c) 2003 Puja Gupta
7383+ * Copyright (c) 2003 Harikesavan Krishnan
7384+ * Copyright (c) 2003-2008 Stony Brook University
7385+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
7386+ *
7387+ * This program is free software; you can redistribute it and/or modify
7388+ * it under the terms of the GNU General Public License version 2 as
7389+ * published by the Free Software Foundation.
7390+ */
7391+
7392+#include "union.h"
7393+
7394+
7395+/*
7396+ * XXX: we need a dummy readpage handler because generic_file_mmap (which we
7397+ * use in unionfs_mmap) checks for the existence of
7398+ * mapping->a_ops->readpage, else it returns -ENOEXEC. The VFS will need to
7399+ * be fixed to allow a file system to define vm_ops->fault without any
7400+ * address_space_ops whatsoever.
7401+ *
7402+ * Otherwise, we don't want to use our readpage method at all.
7403+ */
7404+static int unionfs_readpage(struct file *file, struct page *page)
7405+{
7406+ BUG();
7407+ return -EINVAL;
7408+}
7409+
7410+static int unionfs_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
7411+{
7412+ int err;
7413+ struct file *file, *lower_file;
7414+ struct vm_operations_struct *lower_vm_ops;
7415+ struct vm_area_struct lower_vma;
7416+
7417+ BUG_ON(!vma);
7418+ memcpy(&lower_vma, vma, sizeof(struct vm_area_struct));
7419+ file = lower_vma.vm_file;
7420+ lower_vm_ops = UNIONFS_F(file)->lower_vm_ops;
7421+ BUG_ON(!lower_vm_ops);
7422+
7423+ lower_file = unionfs_lower_file(file);
7424+ BUG_ON(!lower_file);
7425+ /*
7426+ * XXX: vm_ops->fault may be called in parallel. Because we have to
7427+ * resort to temporarily changing the vma->vm_file to point to the
7428+ * lower file, a concurrent invocation of unionfs_fault could see a
7429+ * different value. In this workaround, we keep a different copy of
7430+ * the vma structure in our stack, so we never expose a different
7431+ * value of the vma->vm_file called to us, even temporarily. A
7432+ * better fix would be to change the calling semantics of ->fault to
7433+ * take an explicit file pointer.
7434+ */
7435+ lower_vma.vm_file = lower_file;
7436+ err = lower_vm_ops->fault(&lower_vma, vmf);
7437+ return err;
7438+}
7439+
7440+/*
7441+ * XXX: the default address_space_ops for unionfs is empty. We cannot set
7442+ * our inode->i_mapping->a_ops to NULL because too many code paths expect
7443+ * the a_ops vector to be non-NULL.
7444+ */
7445+struct address_space_operations unionfs_aops = {
7446+ /* empty on purpose */
7447+};
7448+
7449+/*
7450+ * XXX: we need a second, dummy address_space_ops vector, to be used
7451+ * temporarily during unionfs_mmap, because the latter calls
7452+ * generic_file_mmap, which checks if ->readpage exists, else returns
7453+ * -ENOEXEC.
7454+ */
7455+struct address_space_operations unionfs_dummy_aops = {
7456+ .readpage = unionfs_readpage,
7457+};
7458+
7459+struct vm_operations_struct unionfs_vm_ops = {
7460+ .fault = unionfs_fault,
7461+};
7462diff --git a/fs/unionfs/rdstate.c b/fs/unionfs/rdstate.c
7463new file mode 100644
7464index 0000000..06d5374
7465--- /dev/null
7466+++ b/fs/unionfs/rdstate.c
7467@@ -0,0 +1,285 @@
7468+/*
7469+ * Copyright (c) 2003-2008 Erez Zadok
7470+ * Copyright (c) 2003-2006 Charles P. Wright
7471+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
7472+ * Copyright (c) 2005-2006 Junjiro Okajima
7473+ * Copyright (c) 2005 Arun M. Krishnakumar
7474+ * Copyright (c) 2004-2006 David P. Quigley
7475+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
7476+ * Copyright (c) 2003 Puja Gupta
7477+ * Copyright (c) 2003 Harikesavan Krishnan
7478+ * Copyright (c) 2003-2008 Stony Brook University
7479+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
7480+ *
7481+ * This program is free software; you can redistribute it and/or modify
7482+ * it under the terms of the GNU General Public License version 2 as
7483+ * published by the Free Software Foundation.
7484+ */
7485+
7486+#include "union.h"
7487+
7488+/* This file contains the routines for maintaining readdir state. */
7489+
7490+/*
7491+ * There are two structures here, rdstate which is a hash table
7492+ * of the second structure which is a filldir_node.
7493+ */
7494+
7495+/*
7496+ * This is a struct kmem_cache for filldir nodes, because we allocate a lot
7497+ * of them and they shouldn't waste memory. If the node has a small name
7498+ * (as defined by the dentry structure), then we use an inline name to
7499+ * preserve kmalloc space.
7500+ */
7501+static struct kmem_cache *unionfs_filldir_cachep;
7502+
7503+int unionfs_init_filldir_cache(void)
7504+{
7505+ unionfs_filldir_cachep =
7506+ kmem_cache_create("unionfs_filldir",
7507+ sizeof(struct filldir_node), 0,
7508+ SLAB_RECLAIM_ACCOUNT, NULL);
7509+
7510+ return (unionfs_filldir_cachep ? 0 : -ENOMEM);
7511+}
7512+
7513+void unionfs_destroy_filldir_cache(void)
7514+{
7515+ if (unionfs_filldir_cachep)
7516+ kmem_cache_destroy(unionfs_filldir_cachep);
7517+}
7518+
7519+/*
7520+ * This is a tuning parameter that tells us roughly how big to make the
7521+ * hash table in directory entries per page. This isn't perfect, but
7522+ * at least we get a hash table size that shouldn't be too overloaded.
7523+ * The following averages are based on my home directory.
7524+ * 14.44693 Overall
7525+ * 12.29 Single Page Directories
7526+ * 117.93 Multi-page directories
7527+ */
7528+#define DENTPAGE 4096
7529+#define DENTPERONEPAGE 12
7530+#define DENTPERPAGE 118
7531+#define MINHASHSIZE 1
7532+static int guesstimate_hash_size(struct inode *inode)
7533+{
7534+ struct inode *lower_inode;
7535+ int bindex;
7536+ int hashsize = MINHASHSIZE;
7537+
7538+ if (UNIONFS_I(inode)->hashsize > 0)
7539+ return UNIONFS_I(inode)->hashsize;
7540+
7541+ for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) {
7542+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
7543+ if (!lower_inode)
7544+ continue;
7545+
7546+ if (i_size_read(lower_inode) == DENTPAGE)
7547+ hashsize += DENTPERONEPAGE;
7548+ else
7549+ hashsize += (i_size_read(lower_inode) / DENTPAGE) *
7550+ DENTPERPAGE;
7551+ }
7552+
7553+ return hashsize;
7554+}
7555+
7556+int init_rdstate(struct file *file)
7557+{
7558+ BUG_ON(sizeof(loff_t) !=
7559+ (sizeof(unsigned int) + sizeof(unsigned int)));
7560+ BUG_ON(UNIONFS_F(file)->rdstate != NULL);
7561+
7562+ UNIONFS_F(file)->rdstate = alloc_rdstate(file->f_path.dentry->d_inode,
7563+ fbstart(file));
7564+
7565+ return (UNIONFS_F(file)->rdstate ? 0 : -ENOMEM);
7566+}
7567+
7568+struct unionfs_dir_state *find_rdstate(struct inode *inode, loff_t fpos)
7569+{
7570+ struct unionfs_dir_state *rdstate = NULL;
7571+ struct list_head *pos;
7572+
7573+ spin_lock(&UNIONFS_I(inode)->rdlock);
7574+ list_for_each(pos, &UNIONFS_I(inode)->readdircache) {
7575+ struct unionfs_dir_state *r =
7576+ list_entry(pos, struct unionfs_dir_state, cache);
7577+ if (fpos == rdstate2offset(r)) {
7578+ UNIONFS_I(inode)->rdcount--;
7579+ list_del(&r->cache);
7580+ rdstate = r;
7581+ break;
7582+ }
7583+ }
7584+ spin_unlock(&UNIONFS_I(inode)->rdlock);
7585+ return rdstate;
7586+}
7587+
7588+struct unionfs_dir_state *alloc_rdstate(struct inode *inode, int bindex)
7589+{
7590+ int i = 0;
7591+ int hashsize;
7592+ unsigned long mallocsize = sizeof(struct unionfs_dir_state);
7593+ struct unionfs_dir_state *rdstate;
7594+
7595+ hashsize = guesstimate_hash_size(inode);
7596+ mallocsize += hashsize * sizeof(struct list_head);
7597+ mallocsize = __roundup_pow_of_two(mallocsize);
7598+
7599+ /* This should give us about 500 entries anyway. */
7600+ if (mallocsize > PAGE_SIZE)
7601+ mallocsize = PAGE_SIZE;
7602+
7603+ hashsize = (mallocsize - sizeof(struct unionfs_dir_state)) /
7604+ sizeof(struct list_head);
7605+
7606+ rdstate = kmalloc(mallocsize, GFP_KERNEL);
7607+ if (unlikely(!rdstate))
7608+ return NULL;
7609+
7610+ spin_lock(&UNIONFS_I(inode)->rdlock);
7611+ if (UNIONFS_I(inode)->cookie >= (MAXRDCOOKIE - 1))
7612+ UNIONFS_I(inode)->cookie = 1;
7613+ else
7614+ UNIONFS_I(inode)->cookie++;
7615+
7616+ rdstate->cookie = UNIONFS_I(inode)->cookie;
7617+ spin_unlock(&UNIONFS_I(inode)->rdlock);
7618+ rdstate->offset = 1;
7619+ rdstate->access = jiffies;
7620+ rdstate->bindex = bindex;
7621+ rdstate->dirpos = 0;
7622+ rdstate->hashentries = 0;
7623+ rdstate->size = hashsize;
7624+ for (i = 0; i < rdstate->size; i++)
7625+ INIT_LIST_HEAD(&rdstate->list[i]);
7626+
7627+ return rdstate;
7628+}
7629+
7630+static void free_filldir_node(struct filldir_node *node)
7631+{
7632+ if (node->namelen >= DNAME_INLINE_LEN_MIN)
7633+ kfree(node->name);
7634+ kmem_cache_free(unionfs_filldir_cachep, node);
7635+}
7636+
7637+void free_rdstate(struct unionfs_dir_state *state)
7638+{
7639+ struct filldir_node *tmp;
7640+ int i;
7641+
7642+ for (i = 0; i < state->size; i++) {
7643+ struct list_head *head = &(state->list[i]);
7644+ struct list_head *pos, *n;
7645+
7646+ /* traverse the list and deallocate space */
7647+ list_for_each_safe(pos, n, head) {
7648+ tmp = list_entry(pos, struct filldir_node, file_list);
7649+ list_del(&tmp->file_list);
7650+ free_filldir_node(tmp);
7651+ }
7652+ }
7653+
7654+ kfree(state);
7655+}
7656+
7657+struct filldir_node *find_filldir_node(struct unionfs_dir_state *rdstate,
7658+ const char *name, int namelen,
7659+ int is_whiteout)
7660+{
7661+ int index;
7662+ unsigned int hash;
7663+ struct list_head *head;
7664+ struct list_head *pos;
7665+ struct filldir_node *cursor = NULL;
7666+ int found = 0;
7667+
7668+ BUG_ON(namelen <= 0);
7669+
7670+ hash = full_name_hash(name, namelen);
7671+ index = hash % rdstate->size;
7672+
7673+ head = &(rdstate->list[index]);
7674+ list_for_each(pos, head) {
7675+ cursor = list_entry(pos, struct filldir_node, file_list);
7676+
7677+ if (cursor->namelen == namelen && cursor->hash == hash &&
7678+ !strncmp(cursor->name, name, namelen)) {
7679+ /*
7680+ * a duplicate exists, and hence no need to create
7681+ * entry to the list
7682+ */
7683+ found = 1;
7684+
7685+ /*
7686+ * if a duplicate is found in this branch, and is
7687+ * not due to the caller looking for an entry to
7688+ * whiteout, then the file system may be corrupted.
7689+ */
7690+ if (unlikely(!is_whiteout &&
7691+ cursor->bindex == rdstate->bindex))
7692+ printk(KERN_ERR "unionfs: filldir: possible "
7693+ "I/O error: a file is duplicated "
7694+ "in the same branch %d: %s\n",
7695+ rdstate->bindex, cursor->name);
7696+ break;
7697+ }
7698+ }
7699+
7700+ if (!found)
7701+ cursor = NULL;
7702+
7703+ return cursor;
7704+}
7705+
7706+int add_filldir_node(struct unionfs_dir_state *rdstate, const char *name,
7707+ int namelen, int bindex, int whiteout)
7708+{
7709+ struct filldir_node *new;
7710+ unsigned int hash;
7711+ int index;
7712+ int err = 0;
7713+ struct list_head *head;
7714+
7715+ BUG_ON(namelen <= 0);
7716+
7717+ hash = full_name_hash(name, namelen);
7718+ index = hash % rdstate->size;
7719+ head = &(rdstate->list[index]);
7720+
7721+ new = kmem_cache_alloc(unionfs_filldir_cachep, GFP_KERNEL);
7722+ if (unlikely(!new)) {
7723+ err = -ENOMEM;
7724+ goto out;
7725+ }
7726+
7727+ INIT_LIST_HEAD(&new->file_list);
7728+ new->namelen = namelen;
7729+ new->hash = hash;
7730+ new->bindex = bindex;
7731+ new->whiteout = whiteout;
7732+
7733+ if (namelen < DNAME_INLINE_LEN_MIN) {
7734+ new->name = new->iname;
7735+ } else {
7736+ new->name = kmalloc(namelen + 1, GFP_KERNEL);
7737+ if (unlikely(!new->name)) {
7738+ kmem_cache_free(unionfs_filldir_cachep, new);
7739+ new = NULL;
7740+ goto out;
7741+ }
7742+ }
7743+
7744+ memcpy(new->name, name, namelen);
7745+ new->name[namelen] = '\0';
7746+
7747+ rdstate->hashentries++;
7748+
7749+ list_add(&(new->file_list), head);
7750+out:
7751+ return err;
7752+}
7753diff --git a/fs/unionfs/rename.c b/fs/unionfs/rename.c
7754new file mode 100644
7755index 0000000..da7d589
7756--- /dev/null
7757+++ b/fs/unionfs/rename.c
7758@@ -0,0 +1,478 @@
7759+/*
7760+ * Copyright (c) 2003-2008 Erez Zadok
7761+ * Copyright (c) 2003-2006 Charles P. Wright
7762+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
7763+ * Copyright (c) 2005-2006 Junjiro Okajima
7764+ * Copyright (c) 2005 Arun M. Krishnakumar
7765+ * Copyright (c) 2004-2006 David P. Quigley
7766+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
7767+ * Copyright (c) 2003 Puja Gupta
7768+ * Copyright (c) 2003 Harikesavan Krishnan
7769+ * Copyright (c) 2003-2008 Stony Brook University
7770+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
7771+ *
7772+ * This program is free software; you can redistribute it and/or modify
7773+ * it under the terms of the GNU General Public License version 2 as
7774+ * published by the Free Software Foundation.
7775+ */
7776+
7777+#include "union.h"
7778+
7779+/*
7780+ * This is a helper function for rename, used when rename ends up with hosed
7781+ * over dentries and we need to revert.
7782+ */
7783+static int unionfs_refresh_lower_dentry(struct dentry *dentry, int bindex)
7784+{
7785+ struct dentry *lower_dentry;
7786+ struct dentry *lower_parent;
7787+ int err = 0;
7788+
7789+ verify_locked(dentry);
7790+
7791+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_CHILD);
7792+ lower_parent = unionfs_lower_dentry_idx(dentry->d_parent, bindex);
7793+ unionfs_unlock_dentry(dentry->d_parent);
7794+
7795+ BUG_ON(!S_ISDIR(lower_parent->d_inode->i_mode));
7796+
7797+ lower_dentry = lookup_one_len(dentry->d_name.name, lower_parent,
7798+ dentry->d_name.len);
7799+ if (IS_ERR(lower_dentry)) {
7800+ err = PTR_ERR(lower_dentry);
7801+ goto out;
7802+ }
7803+
7804+ dput(unionfs_lower_dentry_idx(dentry, bindex));
7805+ iput(unionfs_lower_inode_idx(dentry->d_inode, bindex));
7806+ unionfs_set_lower_inode_idx(dentry->d_inode, bindex, NULL);
7807+
7808+ if (!lower_dentry->d_inode) {
7809+ dput(lower_dentry);
7810+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
7811+ } else {
7812+ unionfs_set_lower_dentry_idx(dentry, bindex, lower_dentry);
7813+ unionfs_set_lower_inode_idx(dentry->d_inode, bindex,
7814+ igrab(lower_dentry->d_inode));
7815+ }
7816+
7817+out:
7818+ return err;
7819+}
7820+
7821+static int __unionfs_rename(struct inode *old_dir, struct dentry *old_dentry,
7822+ struct inode *new_dir, struct dentry *new_dentry,
7823+ int bindex)
7824+{
7825+ int err = 0;
7826+ struct dentry *lower_old_dentry;
7827+ struct dentry *lower_new_dentry;
7828+ struct dentry *lower_old_dir_dentry;
7829+ struct dentry *lower_new_dir_dentry;
7830+ struct dentry *trap;
7831+
7832+ lower_new_dentry = unionfs_lower_dentry_idx(new_dentry, bindex);
7833+ lower_old_dentry = unionfs_lower_dentry_idx(old_dentry, bindex);
7834+
7835+ if (!lower_new_dentry) {
7836+ lower_new_dentry =
7837+ create_parents(new_dentry->d_parent->d_inode,
7838+ new_dentry, new_dentry->d_name.name,
7839+ bindex);
7840+ if (IS_ERR(lower_new_dentry)) {
7841+ err = PTR_ERR(lower_new_dentry);
7842+ if (IS_COPYUP_ERR(err))
7843+ goto out;
7844+ printk(KERN_ERR "unionfs: error creating directory "
7845+ "tree for rename, bindex=%d err=%d\n",
7846+ bindex, err);
7847+ goto out;
7848+ }
7849+ }
7850+
7851+ /* check for and remove whiteout, if any */
7852+ err = check_unlink_whiteout(new_dentry, lower_new_dentry, bindex);
7853+ if (err > 0) /* ignore if whiteout found and successfully removed */
7854+ err = 0;
7855+ if (err)
7856+ goto out;
7857+
7858+ /* check of old_dentry branch is writable */
7859+ err = is_robranch_super(old_dentry->d_sb, bindex);
7860+ if (err)
7861+ goto out;
7862+
7863+ dget(lower_old_dentry);
7864+ dget(lower_new_dentry);
7865+ lower_old_dir_dentry = dget_parent(lower_old_dentry);
7866+ lower_new_dir_dentry = dget_parent(lower_new_dentry);
7867+
7868+ /* see Documentation/filesystems/unionfs/issues.txt */
7869+ lockdep_off();
7870+ trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
7871+ /* source should not be ancenstor of target */
7872+ if (trap == lower_old_dentry) {
7873+ err = -EINVAL;
7874+ goto out_err_unlock;
7875+ }
7876+ /* target should not be ancenstor of source */
7877+ if (trap == lower_new_dentry) {
7878+ err = -ENOTEMPTY;
7879+ goto out_err_unlock;
7880+ }
7881+ err = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
7882+ lower_new_dir_dentry->d_inode, lower_new_dentry);
7883+out_err_unlock:
7884+ if (!err) {
7885+ /* update parent dir times */
7886+ fsstack_copy_attr_times(old_dir, lower_old_dir_dentry->d_inode);
7887+ fsstack_copy_attr_times(new_dir, lower_new_dir_dentry->d_inode);
7888+ }
7889+ unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
7890+ lockdep_on();
7891+
7892+ dput(lower_old_dir_dentry);
7893+ dput(lower_new_dir_dentry);
7894+ dput(lower_old_dentry);
7895+ dput(lower_new_dentry);
7896+
7897+out:
7898+ if (!err) {
7899+ /* Fixup the new_dentry. */
7900+ if (bindex < dbstart(new_dentry))
7901+ dbstart(new_dentry) = bindex;
7902+ else if (bindex > dbend(new_dentry))
7903+ dbend(new_dentry) = bindex;
7904+ }
7905+
7906+ return err;
7907+}
7908+
7909+/*
7910+ * Main rename code. This is sufficiently complex, that it's documented in
7911+ * Documentation/filesystems/unionfs/rename.txt. This routine calls
7912+ * __unionfs_rename() above to perform some of the work.
7913+ */
7914+static int do_unionfs_rename(struct inode *old_dir,
7915+ struct dentry *old_dentry,
7916+ struct inode *new_dir,
7917+ struct dentry *new_dentry)
7918+{
7919+ int err = 0;
7920+ int bindex, bwh_old;
7921+ int old_bstart, old_bend;
7922+ int new_bstart, new_bend;
7923+ int do_copyup = -1;
7924+ struct dentry *parent_dentry;
7925+ int local_err = 0;
7926+ int eio = 0;
7927+ int revert = 0;
7928+
7929+ old_bstart = dbstart(old_dentry);
7930+ bwh_old = old_bstart;
7931+ old_bend = dbend(old_dentry);
7932+ parent_dentry = old_dentry->d_parent;
7933+
7934+ new_bstart = dbstart(new_dentry);
7935+ new_bend = dbend(new_dentry);
7936+
7937+ /* Rename source to destination. */
7938+ err = __unionfs_rename(old_dir, old_dentry, new_dir, new_dentry,
7939+ old_bstart);
7940+ if (err) {
7941+ if (!IS_COPYUP_ERR(err))
7942+ goto out;
7943+ do_copyup = old_bstart - 1;
7944+ } else {
7945+ revert = 1;
7946+ }
7947+
7948+ /*
7949+ * Unlink all instances of destination that exist to the left of
7950+ * bstart of source. On error, revert back, goto out.
7951+ */
7952+ for (bindex = old_bstart - 1; bindex >= new_bstart; bindex--) {
7953+ struct dentry *unlink_dentry;
7954+ struct dentry *unlink_dir_dentry;
7955+
7956+ BUG_ON(bindex < 0);
7957+ unlink_dentry = unionfs_lower_dentry_idx(new_dentry, bindex);
7958+ if (!unlink_dentry)
7959+ continue;
7960+
7961+ unlink_dir_dentry = lock_parent(unlink_dentry);
7962+ err = is_robranch_super(old_dir->i_sb, bindex);
7963+ if (!err)
7964+ err = vfs_unlink(unlink_dir_dentry->d_inode,
7965+ unlink_dentry);
7966+
7967+ fsstack_copy_attr_times(new_dentry->d_parent->d_inode,
7968+ unlink_dir_dentry->d_inode);
7969+ /* propagate number of hard-links */
7970+ new_dentry->d_parent->d_inode->i_nlink =
7971+ unionfs_get_nlinks(new_dentry->d_parent->d_inode);
7972+
7973+ unlock_dir(unlink_dir_dentry);
7974+ if (!err) {
7975+ if (bindex != new_bstart) {
7976+ dput(unlink_dentry);
7977+ unionfs_set_lower_dentry_idx(new_dentry,
7978+ bindex, NULL);
7979+ }
7980+ } else if (IS_COPYUP_ERR(err)) {
7981+ do_copyup = bindex - 1;
7982+ } else if (revert) {
7983+ goto revert;
7984+ }
7985+ }
7986+
7987+ if (do_copyup != -1) {
7988+ for (bindex = do_copyup; bindex >= 0; bindex--) {
7989+ /*
7990+ * copyup the file into some left directory, so that
7991+ * you can rename it
7992+ */
7993+ err = copyup_dentry(old_dentry->d_parent->d_inode,
7994+ old_dentry, old_bstart, bindex,
7995+ old_dentry->d_name.name,
7996+ old_dentry->d_name.len, NULL,
7997+ i_size_read(old_dentry->d_inode));
7998+ /* if copyup failed, try next branch to the left */
7999+ if (err)
8000+ continue;
8001+ bwh_old = bindex;
8002+ err = __unionfs_rename(old_dir, old_dentry,
8003+ new_dir, new_dentry,
8004+ bindex);
8005+ break;
8006+ }
8007+ }
8008+
8009+ /* make it opaque */
8010+ if (S_ISDIR(old_dentry->d_inode->i_mode)) {
8011+ err = make_dir_opaque(old_dentry, dbstart(old_dentry));
8012+ if (err)
8013+ goto revert;
8014+ }
8015+
8016+ /*
8017+ * Create whiteout for source, only if:
8018+ * (1) There is more than one underlying instance of source.
8019+ * (2) We did a copy_up
8020+ */
8021+ if ((old_bstart != old_bend) || (do_copyup != -1)) {
8022+ if (bwh_old < 0) {
8023+ printk(KERN_ERR "unionfs: rename error (bwh_old=%d)\n",
8024+ bwh_old);
8025+ err = -EIO;
8026+ goto out;
8027+ }
8028+ err = create_whiteout(old_dentry, bwh_old);
8029+ if (err) {
8030+ /* can't fix anything now, so we exit with -EIO */
8031+ printk(KERN_ERR "unionfs: can't create a whiteout for "
8032+ "%s in rename!\n", old_dentry->d_name.name);
8033+ err = -EIO;
8034+ }
8035+ }
8036+
8037+out:
8038+ return err;
8039+
8040+revert:
8041+ /* Do revert here. */
8042+ local_err = unionfs_refresh_lower_dentry(new_dentry, old_bstart);
8043+ if (local_err) {
8044+ printk(KERN_ERR "unionfs: revert failed in rename: "
8045+ "the new refresh failed\n");
8046+ eio = -EIO;
8047+ }
8048+
8049+ local_err = unionfs_refresh_lower_dentry(old_dentry, old_bstart);
8050+ if (local_err) {
8051+ printk(KERN_ERR "unionfs: revert failed in rename: "
8052+ "the old refresh failed\n");
8053+ eio = -EIO;
8054+ goto revert_out;
8055+ }
8056+
8057+ if (!unionfs_lower_dentry_idx(new_dentry, bindex) ||
8058+ !unionfs_lower_dentry_idx(new_dentry, bindex)->d_inode) {
8059+ printk(KERN_ERR "unionfs: revert failed in rename: "
8060+ "the object disappeared from under us!\n");
8061+ eio = -EIO;
8062+ goto revert_out;
8063+ }
8064+
8065+ if (unionfs_lower_dentry_idx(old_dentry, bindex) &&
8066+ unionfs_lower_dentry_idx(old_dentry, bindex)->d_inode) {
8067+ printk(KERN_ERR "unionfs: revert failed in rename: "
8068+ "the object was created underneath us!\n");
8069+ eio = -EIO;
8070+ goto revert_out;
8071+ }
8072+
8073+ local_err = __unionfs_rename(new_dir, new_dentry,
8074+ old_dir, old_dentry, old_bstart);
8075+
8076+ /* If we can't fix it, then we cop-out with -EIO. */
8077+ if (local_err) {
8078+ printk(KERN_ERR "unionfs: revert failed in rename!\n");
8079+ eio = -EIO;
8080+ }
8081+
8082+ local_err = unionfs_refresh_lower_dentry(new_dentry, bindex);
8083+ if (local_err)
8084+ eio = -EIO;
8085+ local_err = unionfs_refresh_lower_dentry(old_dentry, bindex);
8086+ if (local_err)
8087+ eio = -EIO;
8088+
8089+revert_out:
8090+ if (eio)
8091+ err = eio;
8092+ return err;
8093+}
8094+
8095+/*
8096+ * We can't copyup a directory, because it may involve huge numbers of
8097+ * children, etc. Doing that in the kernel would be bad, so instead we
8098+ * return EXDEV to the user-space utility that caused this, and let the
8099+ * user-space recurse and ask us to copy up each file separately.
8100+ */
8101+static int may_rename_dir(struct dentry *dentry)
8102+{
8103+ int err, bstart;
8104+
8105+ err = check_empty(dentry, NULL);
8106+ if (err == -ENOTEMPTY) {
8107+ if (is_robranch(dentry))
8108+ return -EXDEV;
8109+ } else if (err) {
8110+ return err;
8111+ }
8112+
8113+ bstart = dbstart(dentry);
8114+ if (dbend(dentry) == bstart || dbopaque(dentry) == bstart)
8115+ return 0;
8116+
8117+ dbstart(dentry) = bstart + 1;
8118+ err = check_empty(dentry, NULL);
8119+ dbstart(dentry) = bstart;
8120+ if (err == -ENOTEMPTY)
8121+ err = -EXDEV;
8122+ return err;
8123+}
8124+
8125+int unionfs_rename(struct inode *old_dir, struct dentry *old_dentry,
8126+ struct inode *new_dir, struct dentry *new_dentry)
8127+{
8128+ int err = 0;
8129+ struct dentry *wh_dentry;
8130+
8131+ unionfs_read_lock(old_dentry->d_sb, UNIONFS_SMUTEX_CHILD);
8132+ unionfs_double_lock_dentry(old_dentry, new_dentry);
8133+
8134+ if (unlikely(!__unionfs_d_revalidate_chain(old_dentry, NULL, false))) {
8135+ err = -ESTALE;
8136+ goto out;
8137+ }
8138+ if (unlikely(!d_deleted(new_dentry) && new_dentry->d_inode &&
8139+ !__unionfs_d_revalidate_chain(new_dentry, NULL, false))) {
8140+ err = -ESTALE;
8141+ goto out;
8142+ }
8143+
8144+ if (!S_ISDIR(old_dentry->d_inode->i_mode))
8145+ err = unionfs_partial_lookup(old_dentry);
8146+ else
8147+ err = may_rename_dir(old_dentry);
8148+
8149+ if (err)
8150+ goto out;
8151+
8152+ err = unionfs_partial_lookup(new_dentry);
8153+ if (err)
8154+ goto out;
8155+
8156+ /*
8157+ * if new_dentry is already lower because of whiteout,
8158+ * simply override it even if the whited-out dir is not empty.
8159+ */
8160+ wh_dentry = find_first_whiteout(new_dentry);
8161+ if (!IS_ERR(wh_dentry)) {
8162+ dput(wh_dentry);
8163+ } else if (new_dentry->d_inode) {
8164+ if (S_ISDIR(old_dentry->d_inode->i_mode) !=
8165+ S_ISDIR(new_dentry->d_inode->i_mode)) {
8166+ err = S_ISDIR(old_dentry->d_inode->i_mode) ?
8167+ -ENOTDIR : -EISDIR;
8168+ goto out;
8169+ }
8170+
8171+ if (S_ISDIR(new_dentry->d_inode->i_mode)) {
8172+ struct unionfs_dir_state *namelist = NULL;
8173+ /* check if this unionfs directory is empty or not */
8174+ err = check_empty(new_dentry, &namelist);
8175+ if (err)
8176+ goto out;
8177+
8178+ if (!is_robranch(new_dentry))
8179+ err = delete_whiteouts(new_dentry,
8180+ dbstart(new_dentry),
8181+ namelist);
8182+
8183+ free_rdstate(namelist);
8184+
8185+ if (err)
8186+ goto out;
8187+ }
8188+ }
8189+
8190+ err = do_unionfs_rename(old_dir, old_dentry, new_dir, new_dentry);
8191+ if (err)
8192+ goto out;
8193+
8194+ /*
8195+ * force re-lookup since the dir on ro branch is not renamed, and
8196+ * lower dentries still indicate the un-renamed ones.
8197+ */
8198+ if (S_ISDIR(old_dentry->d_inode->i_mode))
8199+ atomic_dec(&UNIONFS_D(old_dentry)->generation);
8200+ else
8201+ unionfs_postcopyup_release(old_dentry);
8202+ if (new_dentry->d_inode && !S_ISDIR(new_dentry->d_inode->i_mode)) {
8203+ unionfs_postcopyup_release(new_dentry);
8204+ unionfs_postcopyup_setmnt(new_dentry);
8205+ if (!unionfs_lower_inode(new_dentry->d_inode)) {
8206+ /*
8207+ * If we get here, it means that no copyup was
8208+ * needed, and that a file by the old name already
8209+ * existing on the destination branch; that file got
8210+ * renamed earlier in this function, so all we need
8211+ * to do here is set the lower inode.
8212+ */
8213+ struct inode *inode;
8214+ inode = unionfs_lower_inode(old_dentry->d_inode);
8215+ igrab(inode);
8216+ unionfs_set_lower_inode_idx(new_dentry->d_inode,
8217+ dbstart(new_dentry),
8218+ inode);
8219+ }
8220+ }
8221+ /* if all of this renaming succeeded, update our times */
8222+ unionfs_copy_attr_times(old_dentry->d_inode);
8223+ unionfs_copy_attr_times(new_dentry->d_inode);
8224+ unionfs_check_inode(old_dir);
8225+ unionfs_check_inode(new_dir);
8226+ unionfs_check_dentry(old_dentry);
8227+ unionfs_check_dentry(new_dentry);
8228+
8229+out:
8230+ if (err) /* clear the new_dentry stuff created */
8231+ d_drop(new_dentry);
8232+ unionfs_unlock_dentry(new_dentry);
8233+ unionfs_unlock_dentry(old_dentry);
8234+ unionfs_read_unlock(old_dentry->d_sb);
8235+ return err;
8236+}
8237diff --git a/fs/unionfs/sioq.c b/fs/unionfs/sioq.c
8238new file mode 100644
8239index 0000000..dd45e39
8240--- /dev/null
8241+++ b/fs/unionfs/sioq.c
8242@@ -0,0 +1,101 @@
8243+/*
8244+ * Copyright (c) 2006-2008 Erez Zadok
8245+ * Copyright (c) 2006 Charles P. Wright
8246+ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
8247+ * Copyright (c) 2006 Junjiro Okajima
8248+ * Copyright (c) 2006 David P. Quigley
8249+ * Copyright (c) 2006-2008 Stony Brook University
8250+ * Copyright (c) 2006-2008 The Research Foundation of SUNY
8251+ *
8252+ * This program is free software; you can redistribute it and/or modify
8253+ * it under the terms of the GNU General Public License version 2 as
8254+ * published by the Free Software Foundation.
8255+ */
8256+
8257+#include "union.h"
8258+
8259+/*
8260+ * Super-user IO work Queue - sometimes we need to perform actions which
8261+ * would fail due to the unix permissions on the parent directory (e.g.,
8262+ * rmdir a directory which appears empty, but in reality contains
8263+ * whiteouts).
8264+ */
8265+
8266+static struct workqueue_struct *superio_workqueue;
8267+
8268+int __init init_sioq(void)
8269+{
8270+ int err;
8271+
8272+ superio_workqueue = create_workqueue("unionfs_siod");
8273+ if (!IS_ERR(superio_workqueue))
8274+ return 0;
8275+
8276+ err = PTR_ERR(superio_workqueue);
8277+ printk(KERN_ERR "unionfs: create_workqueue failed %d\n", err);
8278+ superio_workqueue = NULL;
8279+ return err;
8280+}
8281+
8282+void stop_sioq(void)
8283+{
8284+ if (superio_workqueue)
8285+ destroy_workqueue(superio_workqueue);
8286+}
8287+
8288+void run_sioq(work_func_t func, struct sioq_args *args)
8289+{
8290+ INIT_WORK(&args->work, func);
8291+
8292+ init_completion(&args->comp);
8293+ while (!queue_work(superio_workqueue, &args->work)) {
8294+ /* TODO: do accounting if needed */
8295+ schedule();
8296+ }
8297+ wait_for_completion(&args->comp);
8298+}
8299+
8300+void __unionfs_create(struct work_struct *work)
8301+{
8302+ struct sioq_args *args = container_of(work, struct sioq_args, work);
8303+ struct create_args *c = &args->create;
8304+
8305+ args->err = vfs_create(c->parent, c->dentry, c->mode, c->nd);
8306+ complete(&args->comp);
8307+}
8308+
8309+void __unionfs_mkdir(struct work_struct *work)
8310+{
8311+ struct sioq_args *args = container_of(work, struct sioq_args, work);
8312+ struct mkdir_args *m = &args->mkdir;
8313+
8314+ args->err = vfs_mkdir(m->parent, m->dentry, m->mode);
8315+ complete(&args->comp);
8316+}
8317+
8318+void __unionfs_mknod(struct work_struct *work)
8319+{
8320+ struct sioq_args *args = container_of(work, struct sioq_args, work);
8321+ struct mknod_args *m = &args->mknod;
8322+
8323+ args->err = vfs_mknod(m->parent, m->dentry, m->mode, m->dev);
8324+ complete(&args->comp);
8325+}
8326+
8327+void __unionfs_symlink(struct work_struct *work)
8328+{
8329+ struct sioq_args *args = container_of(work, struct sioq_args, work);
8330+ struct symlink_args *s = &args->symlink;
8331+
8332+ args->err = vfs_symlink(s->parent, s->dentry, s->symbuf);
8333+ complete(&args->comp);
8334+}
8335+
8336+void __unionfs_unlink(struct work_struct *work)
8337+{
8338+ struct sioq_args *args = container_of(work, struct sioq_args, work);
8339+ struct unlink_args *u = &args->unlink;
8340+
8341+ args->err = vfs_unlink(u->parent, u->dentry);
8342+ complete(&args->comp);
8343+}
8344diff --git a/fs/unionfs/sioq.h b/fs/unionfs/sioq.h
8345new file mode 100644
8346index 0000000..679a0df
8347--- /dev/null
8348+++ b/fs/unionfs/sioq.h
8349@@ -0,0 +1,91 @@
8350+/*
8351+ * Copyright (c) 2006-2008 Erez Zadok
8352+ * Copyright (c) 2006 Charles P. Wright
8353+ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
8354+ * Copyright (c) 2006 Junjiro Okajima
8355+ * Copyright (c) 2006 David P. Quigley
8356+ * Copyright (c) 2006-2008 Stony Brook University
8357+ * Copyright (c) 2006-2008 The Research Foundation of SUNY
8358+ *
8359+ * This program is free software; you can redistribute it and/or modify
8360+ * it under the terms of the GNU General Public License version 2 as
8361+ * published by the Free Software Foundation.
8362+ */
8363+
8364+#ifndef _SIOQ_H
8365+#define _SIOQ_H
8366+
8367+struct deletewh_args {
8368+ struct unionfs_dir_state *namelist;
8369+ struct dentry *dentry;
8370+ int bindex;
8371+};
8372+
8373+struct is_opaque_args {
8374+ struct dentry *dentry;
8375+};
8376+
8377+struct create_args {
8378+ struct inode *parent;
8379+ struct dentry *dentry;
8380+ umode_t mode;
8381+ struct nameidata *nd;
8382+};
8383+
8384+struct mkdir_args {
8385+ struct inode *parent;
8386+ struct dentry *dentry;
8387+ umode_t mode;
8388+};
8389+
8390+struct mknod_args {
8391+ struct inode *parent;
8392+ struct dentry *dentry;
8393+ umode_t mode;
8394+ dev_t dev;
8395+};
8396+
8397+struct symlink_args {
8398+ struct inode *parent;
8399+ struct dentry *dentry;
8400+ char *symbuf;
8401+};
8402+
8403+struct unlink_args {
8404+ struct inode *parent;
8405+ struct dentry *dentry;
8406+};
8407+
8408+
8409+struct sioq_args {
8410+ struct completion comp;
8411+ struct work_struct work;
8412+ int err;
8413+ void *ret;
8414+
8415+ union {
8416+ struct deletewh_args deletewh;
8417+ struct is_opaque_args is_opaque;
8418+ struct create_args create;
8419+ struct mkdir_args mkdir;
8420+ struct mknod_args mknod;
8421+ struct symlink_args symlink;
8422+ struct unlink_args unlink;
8423+ };
8424+};
8425+
8426+/* Extern definitions for SIOQ functions */
8427+extern int __init init_sioq(void);
8428+extern void stop_sioq(void);
8429+extern void run_sioq(work_func_t func, struct sioq_args *args);
8430+
8431+/* Extern definitions for our privilege escalation helpers */
8432+extern void __unionfs_create(struct work_struct *work);
8433+extern void __unionfs_mkdir(struct work_struct *work);
8434+extern void __unionfs_mknod(struct work_struct *work);
8435+extern void __unionfs_symlink(struct work_struct *work);
8436+extern void __unionfs_unlink(struct work_struct *work);
8437+extern void __delete_whiteouts(struct work_struct *work);
8438+extern void __is_opaque_dir(struct work_struct *work);
8439+
8440+#endif /* not _SIOQ_H */
8441diff --git a/fs/unionfs/subr.c b/fs/unionfs/subr.c
8442new file mode 100644
8443index 0000000..8747d20
8444--- /dev/null
8445+++ b/fs/unionfs/subr.c
8446@@ -0,0 +1,95 @@
8447+/*
8448+ * Copyright (c) 2003-2008 Erez Zadok
8449+ * Copyright (c) 2003-2006 Charles P. Wright
8450+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
8451+ * Copyright (c) 2005-2006 Junjiro Okajima
8452+ * Copyright (c) 2005 Arun M. Krishnakumar
8453+ * Copyright (c) 2004-2006 David P. Quigley
8454+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
8455+ * Copyright (c) 2003 Puja Gupta
8456+ * Copyright (c) 2003 Harikesavan Krishnan
8457+ * Copyright (c) 2003-2008 Stony Brook University
8458+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
8459+ *
8460+ * This program is free software; you can redistribute it and/or modify
8461+ * it under the terms of the GNU General Public License version 2 as
8462+ * published by the Free Software Foundation.
8463+ */
8464+
8465+#include "union.h"
8466+
8467+/*
8468+ * returns the right n_link value based on the inode type
8469+ */
8470+int unionfs_get_nlinks(const struct inode *inode)
8471+{
8472+ /* don't bother to do all the work since we're unlinked */
8473+ if (inode->i_nlink == 0)
8474+ return 0;
8475+
8476+ if (!S_ISDIR(inode->i_mode))
8477+ return unionfs_lower_inode(inode)->i_nlink;
8478+
8479+ /*
8480+ * For directories, we return 1. The only place that could cares
8481+ * about links is readdir, and there's d_type there so even that
8482+ * doesn't matter.
8483+ */
8484+ return 1;
8485+}
8486+
8487+/* copy a/m/ctime from the lower branch with the newest times */
8488+void unionfs_copy_attr_times(struct inode *upper)
8489+{
8490+ int bindex;
8491+ struct inode *lower;
8492+
8493+ if (!upper)
8494+ return;
8495+ if (ibstart(upper) < 0) {
8496+#ifdef CONFIG_UNION_FS_DEBUG
8497+ WARN_ON(ibstart(upper) < 0);
8498+#endif /* CONFIG_UNION_FS_DEBUG */
8499+ return;
8500+ }
8501+ for (bindex = ibstart(upper); bindex <= ibend(upper); bindex++) {
8502+ lower = unionfs_lower_inode_idx(upper, bindex);
8503+ if (!lower)
8504+ continue; /* not all lower dir objects may exist */
8505+ if (unlikely(timespec_compare(&upper->i_mtime,
8506+ &lower->i_mtime) < 0))
8507+ upper->i_mtime = lower->i_mtime;
8508+ if (unlikely(timespec_compare(&upper->i_ctime,
8509+ &lower->i_ctime) < 0))
8510+ upper->i_ctime = lower->i_ctime;
8511+ if (unlikely(timespec_compare(&upper->i_atime,
8512+ &lower->i_atime) < 0))
8513+ upper->i_atime = lower->i_atime;
8514+ }
8515+}
8516+
8517+/*
8518+ * A unionfs/fanout version of fsstack_copy_attr_all. Uses a
8519+ * unionfs_get_nlinks to properly calcluate the number of links to a file.
8520+ * Also, copies the max() of all a/m/ctimes for all lower inodes (which is
8521+ * important if the lower inode is a directory type)
8522+ */
8523+void unionfs_copy_attr_all(struct inode *dest,
8524+ const struct inode *src)
8525+{
8526+ dest->i_mode = src->i_mode;
8527+ dest->i_uid = src->i_uid;
8528+ dest->i_gid = src->i_gid;
8529+ dest->i_rdev = src->i_rdev;
8530+
8531+ unionfs_copy_attr_times(dest);
8532+
8533+ dest->i_blkbits = src->i_blkbits;
8534+ dest->i_flags = src->i_flags;
8535+
8536+ /*
8537+ * Update the nlinks AFTER updating the above fields, because the
8538+ * get_links callback may depend on them.
8539+ */
8540+ dest->i_nlink = unionfs_get_nlinks(dest);
8541+}
8542diff --git a/fs/unionfs/super.c b/fs/unionfs/super.c
8543new file mode 100644
8544index 0000000..e774ef3
8545--- /dev/null
8546+++ b/fs/unionfs/super.c
8547@@ -0,0 +1,1042 @@
8548+/*
8549+ * Copyright (c) 2003-2008 Erez Zadok
8550+ * Copyright (c) 2003-2006 Charles P. Wright
8551+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
8552+ * Copyright (c) 2005-2006 Junjiro Okajima
8553+ * Copyright (c) 2005 Arun M. Krishnakumar
8554+ * Copyright (c) 2004-2006 David P. Quigley
8555+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
8556+ * Copyright (c) 2003 Puja Gupta
8557+ * Copyright (c) 2003 Harikesavan Krishnan
8558+ * Copyright (c) 2003-2008 Stony Brook University
8559+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
8560+ *
8561+ * This program is free software; you can redistribute it and/or modify
8562+ * it under the terms of the GNU General Public License version 2 as
8563+ * published by the Free Software Foundation.
8564+ */
8565+
8566+#include "union.h"
8567+
8568+/*
8569+ * The inode cache is used with alloc_inode for both our inode info and the
8570+ * vfs inode.
8571+ */
8572+static struct kmem_cache *unionfs_inode_cachep;
8573+
8574+struct inode *unionfs_iget(struct super_block *sb, unsigned long ino)
8575+{
8576+ int size;
8577+ struct unionfs_inode_info *info;
8578+ struct inode *inode;
8579+
8580+ inode = iget_locked(sb, ino);
8581+ if (!inode)
8582+ return ERR_PTR(-ENOMEM);
8583+ if (!(inode->i_state & I_NEW))
8584+ return inode;
8585+
8586+ info = UNIONFS_I(inode);
8587+ memset(info, 0, offsetof(struct unionfs_inode_info, vfs_inode));
8588+ info->bstart = -1;
8589+ info->bend = -1;
8590+ atomic_set(&info->generation,
8591+ atomic_read(&UNIONFS_SB(inode->i_sb)->generation));
8592+ spin_lock_init(&info->rdlock);
8593+ info->rdcount = 1;
8594+ info->hashsize = -1;
8595+ INIT_LIST_HEAD(&info->readdircache);
8596+
8597+ size = sbmax(inode->i_sb) * sizeof(struct inode *);
8598+ info->lower_inodes = kzalloc(size, GFP_KERNEL);
8599+ if (unlikely(!info->lower_inodes)) {
8600+ printk(KERN_CRIT "unionfs: no kernel memory when allocating "
8601+ "lower-pointer array!\n");
8602+ iget_failed(inode);
8603+ return ERR_PTR(-ENOMEM);
8604+ }
8605+
8606+ inode->i_version++;
8607+ inode->i_op = &unionfs_main_iops;
8608+ inode->i_fop = &unionfs_main_fops;
8609+
8610+ inode->i_mapping->a_ops = &unionfs_aops;
8611+
8612+ /*
8613+ * reset times so unionfs_copy_attr_all can keep out time invariants
8614+ * right (upper inode time being the max of all lower ones).
8615+ */
8616+ inode->i_atime.tv_sec = inode->i_atime.tv_nsec = 0;
8617+ inode->i_mtime.tv_sec = inode->i_mtime.tv_nsec = 0;
8618+ inode->i_ctime.tv_sec = inode->i_ctime.tv_nsec = 0;
8619+ unlock_new_inode(inode);
8620+ return inode;
8621+}
8622+
8623+/*
8624+ * we now define delete_inode, because there are two VFS paths that may
8625+ * destroy an inode: one of them calls clear inode before doing everything
8626+ * else that's needed, and the other is fine. This way we truncate the inode
8627+ * size (and its pages) and then clear our own inode, which will do an iput
8628+ * on our and the lower inode.
8629+ *
8630+ * No need to lock sb info's rwsem.
8631+ */
8632+static void unionfs_delete_inode(struct inode *inode)
8633+{
8634+#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
8635+ spin_lock(&inode->i_lock);
8636+#endif
8637+ i_size_write(inode, 0); /* every f/s seems to do that */
8638+#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
8639+ spin_unlock(&inode->i_lock);
8640+#endif
8641+
8642+ if (inode->i_data.nrpages)
8643+ truncate_inode_pages(&inode->i_data, 0);
8644+
8645+ clear_inode(inode);
8646+}
8647+
8648+/*
8649+ * final actions when unmounting a file system
8650+ *
8651+ * No need to lock rwsem.
8652+ */
8653+static void unionfs_put_super(struct super_block *sb)
8654+{
8655+ int bindex, bstart, bend;
8656+ struct unionfs_sb_info *spd;
8657+ int leaks = 0;
8658+
8659+ spd = UNIONFS_SB(sb);
8660+ if (!spd)
8661+ return;
8662+
8663+ bstart = sbstart(sb);
8664+ bend = sbend(sb);
8665+
8666+ /* Make sure we have no leaks of branchget/branchput. */
8667+ for (bindex = bstart; bindex <= bend; bindex++)
8668+ if (unlikely(branch_count(sb, bindex) != 0)) {
8669+ printk(KERN_CRIT
8670+ "unionfs: branch %d has %d references left!\n",
8671+ bindex, branch_count(sb, bindex));
8672+ leaks = 1;
8673+ }
8674+ BUG_ON(leaks != 0);
8675+
8676+ /* decrement lower super references */
8677+ for (bindex = bstart; bindex <= bend; bindex++) {
8678+ struct super_block *s;
8679+ s = unionfs_lower_super_idx(sb, bindex);
8680+ unionfs_set_lower_super_idx(sb, bindex, NULL);
8681+ atomic_dec(&s->s_active);
8682+ }
8683+
8684+ kfree(spd->dev_name);
8685+ kfree(spd->data);
8686+ kfree(spd);
8687+ sb->s_fs_info = NULL;
8688+}
8689+
8690+/*
8691+ * Since people use this to answer the "How big of a file can I write?"
8692+ * question, we report the size of the highest priority branch as the size of
8693+ * the union.
8694+ */
8695+static int unionfs_statfs(struct dentry *dentry, struct kstatfs *buf)
8696+{
8697+ int err = 0;
8698+ struct super_block *sb;
8699+ struct dentry *lower_dentry;
8700+
8701+ sb = dentry->d_sb;
8702+
8703+ unionfs_read_lock(sb, UNIONFS_SMUTEX_CHILD);
8704+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
8705+
8706+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
8707+ err = -ESTALE;
8708+ goto out;
8709+ }
8710+ unionfs_check_dentry(dentry);
8711+
8712+ lower_dentry = unionfs_lower_dentry(sb->s_root);
8713+ err = vfs_statfs(lower_dentry, buf);
8714+
8715+ /* set return buf to our f/s to avoid confusing user-level utils */
8716+ buf->f_type = UNIONFS_SUPER_MAGIC;
8717+ /*
8718+ * Our maximum file name can is shorter by a few bytes because every
8719+ * file name could potentially be whited-out.
8720+ *
8721+ * XXX: this restriction goes away with ODF.
8722+ */
8723+ unionfs_set_max_namelen(&buf->f_namelen);
8724+
8725+ /*
8726+ * reset two fields to avoid confusing user-land.
8727+ * XXX: is this still necessary?
8728+ */
8729+ memset(&buf->f_fsid, 0, sizeof(__kernel_fsid_t));
8730+ memset(&buf->f_spare, 0, sizeof(buf->f_spare));
8731+
8732+out:
8733+ unionfs_check_dentry(dentry);
8734+ unionfs_unlock_dentry(dentry);
8735+ unionfs_read_unlock(sb);
8736+ return err;
8737+}
8738+
8739+/* handle mode changing during remount */
8740+static noinline_for_stack int do_remount_mode_option(
8741+ char *optarg,
8742+ int cur_branches,
8743+ struct unionfs_data *new_data,
8744+ struct path *new_lower_paths)
8745+{
8746+ int err = -EINVAL;
8747+ int perms, idx;
8748+ char *modename = strchr(optarg, '=');
8749+ struct nameidata nd;
8750+
8751+ /* by now, optarg contains the branch name */
8752+ if (!*optarg) {
8753+ printk(KERN_ERR
8754+ "unionfs: no branch specified for mode change\n");
8755+ goto out;
8756+ }
8757+ if (!modename) {
8758+ printk(KERN_ERR "unionfs: branch \"%s\" requires a mode\n",
8759+ optarg);
8760+ goto out;
8761+ }
8762+ *modename++ = '\0';
8763+ err = parse_branch_mode(modename, &perms);
8764+ if (err) {
8765+ printk(KERN_ERR "unionfs: invalid mode \"%s\" for \"%s\"\n",
8766+ modename, optarg);
8767+ goto out;
8768+ }
8769+
8770+ /*
8771+ * Find matching branch index. For now, this assumes that nothing
8772+ * has been mounted on top of this Unionfs stack. Once we have /odf
8773+ * and cache-coherency resolved, we'll address the branch-path
8774+ * uniqueness.
8775+ */
8776+ err = path_lookup(optarg, LOOKUP_FOLLOW, &nd);
8777+ if (err) {
8778+ printk(KERN_ERR "unionfs: error accessing "
8779+ "lower directory \"%s\" (error %d)\n",
8780+ optarg, err);
8781+ goto out;
8782+ }
8783+ for (idx = 0; idx < cur_branches; idx++)
8784+ if (nd.path.mnt == new_lower_paths[idx].mnt &&
8785+ nd.path.dentry == new_lower_paths[idx].dentry)
8786+ break;
8787+ path_put(&nd.path); /* no longer needed */
8788+ if (idx == cur_branches) {
8789+ err = -ENOENT; /* err may have been reset above */
8790+ printk(KERN_ERR "unionfs: branch \"%s\" "
8791+ "not found\n", optarg);
8792+ goto out;
8793+ }
8794+ /* check/change mode for existing branch */
8795+ /* we don't warn if perms==branchperms */
8796+ new_data[idx].branchperms = perms;
8797+ err = 0;
8798+out:
8799+ return err;
8800+}
8801+
8802+/* handle branch deletion during remount */
8803+static noinline_for_stack int do_remount_del_option(
8804+ char *optarg, int cur_branches,
8805+ struct unionfs_data *new_data,
8806+ struct path *new_lower_paths)
8807+{
8808+ int err = -EINVAL;
8809+ int idx;
8810+ struct nameidata nd;
8811+
8812+ /* optarg contains the branch name to delete */
8813+
8814+ /*
8815+ * Find matching branch index. For now, this assumes that nothing
8816+ * has been mounted on top of this Unionfs stack. Once we have /odf
8817+ * and cache-coherency resolved, we'll address the branch-path
8818+ * uniqueness.
8819+ */
8820+ err = path_lookup(optarg, LOOKUP_FOLLOW, &nd);
8821+ if (err) {
8822+ printk(KERN_ERR "unionfs: error accessing "
8823+ "lower directory \"%s\" (error %d)\n",
8824+ optarg, err);
8825+ goto out;
8826+ }
8827+ for (idx = 0; idx < cur_branches; idx++)
8828+ if (nd.path.mnt == new_lower_paths[idx].mnt &&
8829+ nd.path.dentry == new_lower_paths[idx].dentry)
8830+ break;
8831+ path_put(&nd.path); /* no longer needed */
8832+ if (idx == cur_branches) {
8833+ printk(KERN_ERR "unionfs: branch \"%s\" "
8834+ "not found\n", optarg);
8835+ err = -ENOENT;
8836+ goto out;
8837+ }
8838+ /* check if there are any open files on the branch to be deleted */
8839+ if (atomic_read(&new_data[idx].open_files) > 0) {
8840+ err = -EBUSY;
8841+ goto out;
8842+ }
8843+
8844+ /*
8845+ * Now we have to delete the branch. First, release any handles it
8846+ * has. Then, move the remaining array indexes past "idx" in
8847+ * new_data and new_lower_paths one to the left. Finally, adjust
8848+ * cur_branches.
8849+ */
8850+ path_put(&new_lower_paths[idx]);
8851+
8852+ if (idx < cur_branches - 1) {
8853+ /* if idx==cur_branches-1, we delete last branch: easy */
8854+ memmove(&new_data[idx], &new_data[idx+1],
8855+ (cur_branches - 1 - idx) *
8856+ sizeof(struct unionfs_data));
8857+ memmove(&new_lower_paths[idx], &new_lower_paths[idx+1],
8858+ (cur_branches - 1 - idx) * sizeof(struct path));
8859+ }
8860+
8861+ err = 0;
8862+out:
8863+ return err;
8864+}
8865+
8866+/* handle branch insertion during remount */
8867+static noinline_for_stack int do_remount_add_option(
8868+ char *optarg, int cur_branches,
8869+ struct unionfs_data *new_data,
8870+ struct path *new_lower_paths,
8871+ int *high_branch_id)
8872+{
8873+ int err = -EINVAL;
8874+ int perms;
8875+ int idx = 0; /* default: insert at beginning */
8876+ char *new_branch , *modename = NULL;
8877+ struct nameidata nd;
8878+
8879+ /*
8880+ * optarg can be of several forms:
8881+ *
8882+ * /bar:/foo insert /foo before /bar
8883+ * /bar:/foo=ro insert /foo in ro mode before /bar
8884+ * /foo insert /foo in the beginning (prepend)
8885+ * :/foo insert /foo at the end (append)
8886+ */
8887+ if (*optarg == ':') { /* append? */
8888+ new_branch = optarg + 1; /* skip ':' */
8889+ idx = cur_branches;
8890+ goto found_insertion_point;
8891+ }
8892+ new_branch = strchr(optarg, ':');
8893+ if (!new_branch) { /* prepend? */
8894+ new_branch = optarg;
8895+ goto found_insertion_point;
8896+ }
8897+ *new_branch++ = '\0'; /* holds path+mode of new branch */
8898+
8899+ /*
8900+ * Find matching branch index. For now, this assumes that nothing
8901+ * has been mounted on top of this Unionfs stack. Once we have /odf
8902+ * and cache-coherency resolved, we'll address the branch-path
8903+ * uniqueness.
8904+ */
8905+ err = path_lookup(optarg, LOOKUP_FOLLOW, &nd);
8906+ if (err) {
8907+ printk(KERN_ERR "unionfs: error accessing "
8908+ "lower directory \"%s\" (error %d)\n",
8909+ optarg, err);
8910+ goto out;
8911+ }
8912+ for (idx = 0; idx < cur_branches; idx++)
8913+ if (nd.path.mnt == new_lower_paths[idx].mnt &&
8914+ nd.path.dentry == new_lower_paths[idx].dentry)
8915+ break;
8916+ path_put(&nd.path); /* no longer needed */
8917+ if (idx == cur_branches) {
8918+ printk(KERN_ERR "unionfs: branch \"%s\" "
8919+ "not found\n", optarg);
8920+ err = -ENOENT;
8921+ goto out;
8922+ }
8923+
8924+ /*
8925+ * At this point idx will hold the index where the new branch should
8926+ * be inserted before.
8927+ */
8928+found_insertion_point:
8929+ /* find the mode for the new branch */
8930+ if (new_branch)
8931+ modename = strchr(new_branch, '=');
8932+ if (modename)
8933+ *modename++ = '\0';
8934+ if (!new_branch || !*new_branch) {
8935+ printk(KERN_ERR "unionfs: null new branch\n");
8936+ err = -EINVAL;
8937+ goto out;
8938+ }
8939+ err = parse_branch_mode(modename, &perms);
8940+ if (err) {
8941+ printk(KERN_ERR "unionfs: invalid mode \"%s\" for "
8942+ "branch \"%s\"\n", modename, new_branch);
8943+ goto out;
8944+ }
8945+ err = path_lookup(new_branch, LOOKUP_FOLLOW, &nd);
8946+ if (err) {
8947+ printk(KERN_ERR "unionfs: error accessing "
8948+ "lower directory \"%s\" (error %d)\n",
8949+ new_branch, err);
8950+ goto out;
8951+ }
8952+ /*
8953+ * It's probably safe to check_mode the new branch to insert. Note:
8954+ * we don't allow inserting branches which are unionfs's by
8955+ * themselves (check_branch returns EINVAL in that case). This is
8956+ * because this code base doesn't support stacking unionfs: the ODF
8957+ * code base supports that correctly.
8958+ */
8959+ err = check_branch(&nd);
8960+ if (err) {
8961+ printk(KERN_ERR "unionfs: lower directory "
8962+ "\"%s\" is not a valid branch\n", optarg);
8963+ path_put(&nd.path);
8964+ goto out;
8965+ }
8966+
8967+ /*
8968+ * Now we have to insert the new branch. But first, move the bits
8969+ * to make space for the new branch, if needed. Finally, adjust
8970+ * cur_branches.
8971+ * We don't release nd here; it's kept until umount/remount.
8972+ */
8973+ if (idx < cur_branches) {
8974+ /* if idx==cur_branches, we append: easy */
8975+ memmove(&new_data[idx+1], &new_data[idx],
8976+ (cur_branches - idx) * sizeof(struct unionfs_data));
8977+ memmove(&new_lower_paths[idx+1], &new_lower_paths[idx],
8978+ (cur_branches - idx) * sizeof(struct path));
8979+ }
8980+ new_lower_paths[idx].dentry = nd.path.dentry;
8981+ new_lower_paths[idx].mnt = nd.path.mnt;
8982+
8983+ new_data[idx].sb = nd.path.dentry->d_sb;
8984+ atomic_set(&new_data[idx].open_files, 0);
8985+ new_data[idx].branchperms = perms;
8986+ new_data[idx].branch_id = ++*high_branch_id; /* assign new branch ID */
8987+
8988+ err = 0;
8989+out:
8990+ return err;
8991+}
8992+
8993+
8994+/*
8995+ * Support branch management options on remount.
8996+ *
8997+ * See Documentation/filesystems/unionfs/ for details.
8998+ *
8999+ * @flags: numeric mount options
9000+ * @options: mount options string
9001+ *
9002+ * This function can rearrange a mounted union dynamically, adding and
9003+ * removing branches, including changing branch modes. Clearly this has to
9004+ * be done safely and atomically. Luckily, the VFS already calls this
9005+ * function with lock_super(sb) and lock_kernel() held, preventing
9006+ * concurrent mixing of new mounts, remounts, and unmounts. Moreover,
9007+ * do_remount_sb(), our caller function, already called shrink_dcache_sb(sb)
9008+ * to purge dentries/inodes from our superblock, and also called
9009+ * fsync_super(sb) to purge any dirty pages. So we're good.
9010+ *
9011+ * XXX: however, our remount code may also need to invalidate mapped pages
9012+ * so as to force them to be re-gotten from the (newly reconfigured) lower
9013+ * branches. This has to wait for proper mmap and cache coherency support
9014+ * in the VFS.
9015+ *
9016+ */
9017+static int unionfs_remount_fs(struct super_block *sb, int *flags,
9018+ char *options)
9019+{
9020+ int err = 0;
9021+ int i;
9022+ char *optionstmp, *tmp_to_free; /* kstrdup'ed of "options" */
9023+ char *optname;
9024+ int cur_branches = 0; /* no. of current branches */
9025+ int new_branches = 0; /* no. of branches actually left in the end */
9026+ int add_branches; /* est. no. of branches to add */
9027+ int del_branches; /* est. no. of branches to del */
9028+ int max_branches; /* max possible no. of branches */
9029+ struct unionfs_data *new_data = NULL, *tmp_data = NULL;
9030+ struct path *new_lower_paths = NULL, *tmp_lower_paths = NULL;
9031+ struct inode **new_lower_inodes = NULL;
9032+ int new_high_branch_id; /* new high branch ID */
9033+ int size; /* memory allocation size, temp var */
9034+ int old_ibstart, old_ibend;
9035+
9036+ unionfs_write_lock(sb);
9037+
9038+ /*
9039+ * The VFS will take care of "ro" and "rw" flags, and we can safely
9040+ * ignore MS_SILENT, but anything else left over is an error. So we
9041+ * need to check if any other flags may have been passed (none are
9042+ * allowed/supported as of now).
9043+ */
9044+ if ((*flags & ~(MS_RDONLY | MS_SILENT)) != 0) {
9045+ printk(KERN_ERR
9046+ "unionfs: remount flags 0x%x unsupported\n", *flags);
9047+ err = -EINVAL;
9048+ goto out_error;
9049+ }
9050+
9051+ /*
9052+ * If 'options' is NULL, it's probably because the user just changed
9053+ * the union to a "ro" or "rw" and the VFS took care of it. So
9054+ * nothing to do and we're done.
9055+ */
9056+ if (!options || options[0] == '\0')
9057+ goto out_error;
9058+
9059+ /*
9060+ * Find out how many branches we will have in the end, counting
9061+ * "add" and "del" commands. Copy the "options" string because
9062+ * strsep modifies the string and we need it later.
9063+ */
9064+ tmp_to_free = kstrdup(options, GFP_KERNEL);
9065+ optionstmp = tmp_to_free;
9066+ if (unlikely(!optionstmp)) {
9067+ err = -ENOMEM;
9068+ goto out_free;
9069+ }
9070+ cur_branches = sbmax(sb); /* current no. branches */
9071+ new_branches = sbmax(sb);
9072+ del_branches = 0;
9073+ add_branches = 0;
9074+ new_high_branch_id = sbhbid(sb); /* save current high_branch_id */
9075+ while ((optname = strsep(&optionstmp, ",")) != NULL) {
9076+ char *optarg;
9077+
9078+ if (!optname || !*optname)
9079+ continue;
9080+
9081+ optarg = strchr(optname, '=');
9082+ if (optarg)
9083+ *optarg++ = '\0';
9084+
9085+ if (!strcmp("add", optname))
9086+ add_branches++;
9087+ else if (!strcmp("del", optname))
9088+ del_branches++;
9089+ }
9090+ kfree(tmp_to_free);
9091+ /* after all changes, will we have at least one branch left? */
9092+ if ((new_branches + add_branches - del_branches) < 1) {
9093+ printk(KERN_ERR
9094+ "unionfs: no branches left after remount\n");
9095+ err = -EINVAL;
9096+ goto out_free;
9097+ }
9098+
9099+ /*
9100+ * Since we haven't actually parsed all the add/del options, nor
9101+ * have we checked them for errors, we don't know for sure how many
9102+ * branches we will have after all changes have taken place. In
9103+ * fact, the total number of branches left could be less than what
9104+ * we have now. So we need to allocate space for a temporary
9105+ * placeholder that is at least as large as the maximum number of
9106+ * branches we *could* have, which is the current number plus all
9107+ * the additions. Once we're done with these temp placeholders, we
9108+ * may have to re-allocate the final size, copy over from the temp,
9109+ * and then free the temps (done near the end of this function).
9110+ */
9111+ max_branches = cur_branches + add_branches;
9112+ /* allocate space for new pointers to lower dentry */
9113+ tmp_data = kcalloc(max_branches,
9114+ sizeof(struct unionfs_data), GFP_KERNEL);
9115+ if (unlikely(!tmp_data)) {
9116+ err = -ENOMEM;
9117+ goto out_free;
9118+ }
9119+ /* allocate space for new pointers to lower paths */
9120+ tmp_lower_paths = kcalloc(max_branches,
9121+ sizeof(struct path), GFP_KERNEL);
9122+ if (unlikely(!tmp_lower_paths)) {
9123+ err = -ENOMEM;
9124+ goto out_free;
9125+ }
9126+ /* copy current info into new placeholders, incrementing refcnts */
9127+ memcpy(tmp_data, UNIONFS_SB(sb)->data,
9128+ cur_branches * sizeof(struct unionfs_data));
9129+ memcpy(tmp_lower_paths, UNIONFS_D(sb->s_root)->lower_paths,
9130+ cur_branches * sizeof(struct path));
9131+ for (i = 0; i < cur_branches; i++)
9132+ path_get(&tmp_lower_paths[i]); /* drop refs at end of fxn */
9133+
9134+ /*******************************************************************
9135+ * For each branch command, do path_lookup on the requested branch,
9136+ * and apply the change to a temp branch list. To handle errors, we
9137+ * already dup'ed the old arrays (above), and increased the refcnts
9138+ * on various f/s objects. So now we can do all the path_lookups
9139+ * and branch-management commands on the new arrays. If it fail mid
9140+ * way, we free the tmp arrays and *put all objects. If we succeed,
9141+ * then we free old arrays and *put its objects, and then replace
9142+ * the arrays with the new tmp list (we may have to re-allocate the
9143+ * memory because the temp lists could have been larger than what we
9144+ * actually needed).
9145+ *******************************************************************/
9146+
9147+ while ((optname = strsep(&options, ",")) != NULL) {
9148+ char *optarg;
9149+
9150+ if (!optname || !*optname)
9151+ continue;
9152+ /*
9153+ * At this stage optname holds a comma-delimited option, but
9154+ * without the commas. Next, we need to break the string on
9155+ * the '=' symbol to separate CMD=ARG, where ARG itself can
9156+ * be KEY=VAL. For example, in mode=/foo=rw, CMD is "mode",
9157+ * KEY is "/foo", and VAL is "rw".
9158+ */
9159+ optarg = strchr(optname, '=');
9160+ if (optarg)
9161+ *optarg++ = '\0';
9162+ /* incgen remount option (instead of old ioctl) */
9163+ if (!strcmp("incgen", optname)) {
9164+ err = 0;
9165+ goto out_no_change;
9166+ }
9167+
9168+ /*
9169+ * All of our options take an argument now. (Insert ones
9170+ * that don't above this check.) So at this stage optname
9171+ * contains the CMD part and optarg contains the ARG part.
9172+ */
9173+ if (!optarg || !*optarg) {
9174+ printk(KERN_ERR "unionfs: all remount options require "
9175+ "an argument (%s)\n", optname);
9176+ err = -EINVAL;
9177+ goto out_release;
9178+ }
9179+
9180+ if (!strcmp("add", optname)) {
9181+ err = do_remount_add_option(optarg, new_branches,
9182+ tmp_data,
9183+ tmp_lower_paths,
9184+ &new_high_branch_id);
9185+ if (err)
9186+ goto out_release;
9187+ new_branches++;
9188+ if (new_branches > UNIONFS_MAX_BRANCHES) {
9189+ printk(KERN_ERR "unionfs: command exceeds "
9190+ "%d branches\n", UNIONFS_MAX_BRANCHES);
9191+ err = -E2BIG;
9192+ goto out_release;
9193+ }
9194+ continue;
9195+ }
9196+ if (!strcmp("del", optname)) {
9197+ err = do_remount_del_option(optarg, new_branches,
9198+ tmp_data,
9199+ tmp_lower_paths);
9200+ if (err)
9201+ goto out_release;
9202+ new_branches--;
9203+ continue;
9204+ }
9205+ if (!strcmp("mode", optname)) {
9206+ err = do_remount_mode_option(optarg, new_branches,
9207+ tmp_data,
9208+ tmp_lower_paths);
9209+ if (err)
9210+ goto out_release;
9211+ continue;
9212+ }
9213+
9214+ /*
9215+ * When you use "mount -o remount,ro", mount(8) will
9216+ * reportedly pass the original dirs= string from
9217+ * /proc/mounts. So for now, we have to ignore dirs= and
9218+ * not consider it an error, unless we want to allow users
9219+ * to pass dirs= in remount. Note that to allow the VFS to
9220+ * actually process the ro/rw remount options, we have to
9221+ * return 0 from this function.
9222+ */
9223+ if (!strcmp("dirs", optname)) {
9224+ printk(KERN_WARNING
9225+ "unionfs: remount ignoring option \"%s\"\n",
9226+ optname);
9227+ continue;
9228+ }
9229+
9230+ err = -EINVAL;
9231+ printk(KERN_ERR
9232+ "unionfs: unrecognized option \"%s\"\n", optname);
9233+ goto out_release;
9234+ }
9235+
9236+out_no_change:
9237+
9238+ /******************************************************************
9239+ * WE'RE ALMOST DONE: check if leftmost branch might be read-only,
9240+ * see if we need to allocate a small-sized new vector, copy the
9241+ * vectors to their correct place, release the refcnt of the older
9242+ * ones, and return. Also handle invalidating any pages that will
9243+ * have to be re-read.
9244+ *******************************************************************/
9245+
9246+ if (!(tmp_data[0].branchperms & MAY_WRITE)) {
9247+ printk(KERN_ERR "unionfs: leftmost branch cannot be read-only "
9248+ "(use \"remount,ro\" to create a read-only union)\n");
9249+ err = -EINVAL;
9250+ goto out_release;
9251+ }
9252+
9253+ /* (re)allocate space for new pointers to lower dentry */
9254+ size = new_branches * sizeof(struct unionfs_data);
9255+ new_data = krealloc(tmp_data, size, GFP_KERNEL);
9256+ if (unlikely(!new_data)) {
9257+ err = -ENOMEM;
9258+ goto out_release;
9259+ }
9260+
9261+ /* allocate space for new pointers to lower paths */
9262+ size = new_branches * sizeof(struct path);
9263+ new_lower_paths = krealloc(tmp_lower_paths, size, GFP_KERNEL);
9264+ if (unlikely(!new_lower_paths)) {
9265+ err = -ENOMEM;
9266+ goto out_release;
9267+ }
9268+
9269+ /* allocate space for new pointers to lower inodes */
9270+ new_lower_inodes = kcalloc(new_branches,
9271+ sizeof(struct inode *), GFP_KERNEL);
9272+ if (unlikely(!new_lower_inodes)) {
9273+ err = -ENOMEM;
9274+ goto out_release;
9275+ }
9276+
9277+ /*
9278+ * OK, just before we actually put the new set of branches in place,
9279+ * we need to ensure that our own f/s has no dirty objects left.
9280+ * Luckily, do_remount_sb() already calls shrink_dcache_sb(sb) and
9281+ * fsync_super(sb), taking care of dentries, inodes, and dirty
9282+ * pages. So all that's left is for us to invalidate any leftover
9283+ * (non-dirty) pages to ensure that they will be re-read from the
9284+ * new lower branches (and to support mmap).
9285+ */
9286+
9287+ /*
9288+ * Once we finish the remounting successfully, our superblock
9289+ * generation number will have increased. This will be detected by
9290+ * our dentry-revalidation code upon subsequent f/s operations
9291+ * through unionfs. The revalidation code will rebuild the union of
9292+ * lower inodes for a given unionfs inode and invalidate any pages
9293+ * of such "stale" inodes (by calling our purge_inode_data
9294+ * function). This revalidation will happen lazily and
9295+ * incrementally, as users perform operations on cached inodes. We
9296+ * would like to encourage this revalidation to happen sooner if
9297+ * possible, so we like to try to invalidate as many other pages in
9298+ * our superblock as we can. We used to call drop_pagecache_sb() or
9299+ * a variant thereof, but either method was racy (drop_caches alone
9300+ * is known to be racy). So now we let the revalidation happen on a
9301+ * per file basis in ->d_revalidate.
9302+ */
9303+
9304+ /* grab new lower super references; release old ones */
9305+ for (i = 0; i < new_branches; i++)
9306+ atomic_inc(&new_data[i].sb->s_active);
9307+ for (i = 0; i < sbmax(sb); i++)
9308+ atomic_dec(&UNIONFS_SB(sb)->data[i].sb->s_active);
9309+
9310+ /* copy new vectors into their correct place */
9311+ tmp_data = UNIONFS_SB(sb)->data;
9312+ UNIONFS_SB(sb)->data = new_data;
9313+ new_data = NULL; /* so don't free good pointers below */
9314+ tmp_lower_paths = UNIONFS_D(sb->s_root)->lower_paths;
9315+ UNIONFS_D(sb->s_root)->lower_paths = new_lower_paths;
9316+ new_lower_paths = NULL; /* so don't free good pointers below */
9317+
9318+ /* update our unionfs_sb_info and root dentry index of last branch */
9319+ i = sbmax(sb); /* save no. of branches to release at end */
9320+ sbend(sb) = new_branches - 1;
9321+ dbend(sb->s_root) = new_branches - 1;
9322+ old_ibstart = ibstart(sb->s_root->d_inode);
9323+ old_ibend = ibend(sb->s_root->d_inode);
9324+ ibend(sb->s_root->d_inode) = new_branches - 1;
9325+ UNIONFS_D(sb->s_root)->bcount = new_branches;
9326+ new_branches = i; /* no. of branches to release below */
9327+
9328+ /*
9329+ * Update lower inodes: 3 steps
9330+ * 1. grab ref on all new lower inodes
9331+ */
9332+ for (i = dbstart(sb->s_root); i <= dbend(sb->s_root); i++) {
9333+ struct dentry *lower_dentry =
9334+ unionfs_lower_dentry_idx(sb->s_root, i);
9335+ igrab(lower_dentry->d_inode);
9336+ new_lower_inodes[i] = lower_dentry->d_inode;
9337+ }
9338+ /* 2. release reference on all older lower inodes */
9339+ iput_lowers(sb->s_root->d_inode, old_ibstart, old_ibend, true);
9340+ /* 3. update root dentry's inode to new lower_inodes array */
9341+ UNIONFS_I(sb->s_root->d_inode)->lower_inodes = new_lower_inodes;
9342+ new_lower_inodes = NULL;
9343+
9344+ /* maxbytes may have changed */
9345+ sb->s_maxbytes = unionfs_lower_super_idx(sb, 0)->s_maxbytes;
9346+ /* update high branch ID */
9347+ sbhbid(sb) = new_high_branch_id;
9348+
9349+ /* update our sb->generation for revalidating objects */
9350+ i = atomic_inc_return(&UNIONFS_SB(sb)->generation);
9351+ atomic_set(&UNIONFS_D(sb->s_root)->generation, i);
9352+ atomic_set(&UNIONFS_I(sb->s_root->d_inode)->generation, i);
9353+ if (!(*flags & MS_SILENT))
9354+ pr_info("unionfs: %s: new generation number %d\n",
9355+ UNIONFS_SB(sb)->dev_name, i);
9356+ /* finally, update the root dentry's times */
9357+ unionfs_copy_attr_times(sb->s_root->d_inode);
9358+ err = 0; /* reset to success */
9359+
9360+ /*
9361+ * The code above falls through to the next label, and releases the
9362+ * refcnts of the older ones (stored in tmp_*): if we fell through
9363+ * here, it means success. However, if we jump directly to this
9364+ * label from any error above, then an error occurred after we
9365+ * grabbed various refcnts, and so we have to release the
9366+ * temporarily constructed structures.
9367+ */
9368+out_release:
9369+ /* no need to cleanup/release anything in tmp_data */
9370+ if (tmp_lower_paths)
9371+ for (i = 0; i < new_branches; i++)
9372+ path_put(&tmp_lower_paths[i]);
9373+out_free:
9374+ kfree(tmp_lower_paths);
9375+ kfree(tmp_data);
9376+ kfree(new_lower_paths);
9377+ kfree(new_data);
9378+ kfree(new_lower_inodes);
9379+out_error:
9380+ unionfs_check_dentry(sb->s_root);
9381+ unionfs_write_unlock(sb);
9382+ return err;
9383+}
9384+
9385+/*
9386+ * Called by iput() when the inode reference count reached zero
9387+ * and the inode is not hashed anywhere. Used to clear anything
9388+ * that needs to be, before the inode is completely destroyed and put
9389+ * on the inode free list.
9390+ *
9391+ * No need to lock sb info's rwsem.
9392+ */
9393+static void unionfs_clear_inode(struct inode *inode)
9394+{
9395+ int bindex, bstart, bend;
9396+ struct inode *lower_inode;
9397+ struct list_head *pos, *n;
9398+ struct unionfs_dir_state *rdstate;
9399+
9400+ list_for_each_safe(pos, n, &UNIONFS_I(inode)->readdircache) {
9401+ rdstate = list_entry(pos, struct unionfs_dir_state, cache);
9402+ list_del(&rdstate->cache);
9403+ free_rdstate(rdstate);
9404+ }
9405+
9406+ /*
9407+ * Decrement a reference to a lower_inode, which was incremented
9408+ * by our read_inode when it was created initially.
9409+ */
9410+ bstart = ibstart(inode);
9411+ bend = ibend(inode);
9412+ if (bstart >= 0) {
9413+ for (bindex = bstart; bindex <= bend; bindex++) {
9414+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
9415+ if (!lower_inode)
9416+ continue;
9417+ unionfs_set_lower_inode_idx(inode, bindex, NULL);
9418+ /* see Documentation/filesystems/unionfs/issues.txt */
9419+ lockdep_off();
9420+ iput(lower_inode);
9421+ lockdep_on();
9422+ }
9423+ }
9424+
9425+ kfree(UNIONFS_I(inode)->lower_inodes);
9426+ UNIONFS_I(inode)->lower_inodes = NULL;
9427+}
9428+
9429+static struct inode *unionfs_alloc_inode(struct super_block *sb)
9430+{
9431+ struct unionfs_inode_info *i;
9432+
9433+ i = kmem_cache_alloc(unionfs_inode_cachep, GFP_KERNEL);
9434+ if (unlikely(!i))
9435+ return NULL;
9436+
9437+ /* memset everything up to the inode to 0 */
9438+ memset(i, 0, offsetof(struct unionfs_inode_info, vfs_inode));
9439+
9440+ i->vfs_inode.i_version = 1;
9441+ return &i->vfs_inode;
9442+}
9443+
9444+static void unionfs_destroy_inode(struct inode *inode)
9445+{
9446+ kmem_cache_free(unionfs_inode_cachep, UNIONFS_I(inode));
9447+}
9448+
9449+/* unionfs inode cache constructor */
9450+static void init_once(void *obj)
9451+{
9452+ struct unionfs_inode_info *i = obj;
9453+
9454+ inode_init_once(&i->vfs_inode);
9455+}
9456+
9457+int unionfs_init_inode_cache(void)
9458+{
9459+ int err = 0;
9460+
9461+ unionfs_inode_cachep =
9462+ kmem_cache_create("unionfs_inode_cache",
9463+ sizeof(struct unionfs_inode_info), 0,
9464+ SLAB_RECLAIM_ACCOUNT, init_once);
9465+ if (unlikely(!unionfs_inode_cachep))
9466+ err = -ENOMEM;
9467+ return err;
9468+}
9469+
9470+/* unionfs inode cache destructor */
9471+void unionfs_destroy_inode_cache(void)
9472+{
9473+ if (unionfs_inode_cachep)
9474+ kmem_cache_destroy(unionfs_inode_cachep);
9475+}
9476+
9477+/*
9478+ * Called when we have a dirty inode, right here we only throw out
9479+ * parts of our readdir list that are too old.
9480+ *
9481+ * No need to grab sb info's rwsem.
9482+ */
9483+static int unionfs_write_inode(struct inode *inode, int sync)
9484+{
9485+ struct list_head *pos, *n;
9486+ struct unionfs_dir_state *rdstate;
9487+
9488+ spin_lock(&UNIONFS_I(inode)->rdlock);
9489+ list_for_each_safe(pos, n, &UNIONFS_I(inode)->readdircache) {
9490+ rdstate = list_entry(pos, struct unionfs_dir_state, cache);
9491+ /* We keep this list in LRU order. */
9492+ if ((rdstate->access + RDCACHE_JIFFIES) > jiffies)
9493+ break;
9494+ UNIONFS_I(inode)->rdcount--;
9495+ list_del(&rdstate->cache);
9496+ free_rdstate(rdstate);
9497+ }
9498+ spin_unlock(&UNIONFS_I(inode)->rdlock);
9499+
9500+ return 0;
9501+}
9502+
9503+/*
9504+ * Used only in nfs, to kill any pending RPC tasks, so that subsequent
9505+ * code can actually succeed and won't leave tasks that need handling.
9506+ */
9507+static void unionfs_umount_begin(struct super_block *sb)
9508+{
9509+ struct super_block *lower_sb;
9510+ int bindex, bstart, bend;
9511+
9512+ unionfs_read_lock(sb, UNIONFS_SMUTEX_CHILD);
9513+
9514+ bstart = sbstart(sb);
9515+ bend = sbend(sb);
9516+ for (bindex = bstart; bindex <= bend; bindex++) {
9517+ lower_sb = unionfs_lower_super_idx(sb, bindex);
9518+
9519+ if (lower_sb && lower_sb->s_op &&
9520+ lower_sb->s_op->umount_begin)
9521+ lower_sb->s_op->umount_begin(lower_sb);
9522+ }
9523+
9524+ unionfs_read_unlock(sb);
9525+}
9526+
9527+static int unionfs_show_options(struct seq_file *m, struct vfsmount *mnt)
9528+{
9529+ struct super_block *sb = mnt->mnt_sb;
9530+ int ret = 0;
9531+ char *tmp_page;
9532+ char *path;
9533+ int bindex, bstart, bend;
9534+ int perms;
9535+
9536+ unionfs_read_lock(sb, UNIONFS_SMUTEX_CHILD);
9537+
9538+ unionfs_lock_dentry(sb->s_root, UNIONFS_DMUTEX_CHILD);
9539+
9540+ tmp_page = (char *) __get_free_page(GFP_KERNEL);
9541+ if (unlikely(!tmp_page)) {
9542+ ret = -ENOMEM;
9543+ goto out;
9544+ }
9545+
9546+ bstart = sbstart(sb);
9547+ bend = sbend(sb);
9548+
9549+ seq_printf(m, ",dirs=");
9550+ for (bindex = bstart; bindex <= bend; bindex++) {
9551+ struct path p;
9552+ p.dentry = unionfs_lower_dentry_idx(sb->s_root, bindex);
9553+ p.mnt = unionfs_lower_mnt_idx(sb->s_root, bindex);
9554+ path = d_path(&p, tmp_page, PAGE_SIZE);
9555+ if (IS_ERR(path)) {
9556+ ret = PTR_ERR(path);
9557+ goto out;
9558+ }
9559+
9560+ perms = branchperms(sb, bindex);
9561+
9562+ seq_printf(m, "%s=%s", path,
9563+ perms & MAY_WRITE ? "rw" : "ro");
9564+ if (bindex != bend)
9565+ seq_printf(m, ":");
9566+ }
9567+
9568+out:
9569+ free_page((unsigned long) tmp_page);
9570+
9571+ unionfs_unlock_dentry(sb->s_root);
9572+
9573+ unionfs_read_unlock(sb);
9574+
9575+ return ret;
9576+}
9577+
9578+struct super_operations unionfs_sops = {
9579+ .delete_inode = unionfs_delete_inode,
9580+ .put_super = unionfs_put_super,
9581+ .statfs = unionfs_statfs,
9582+ .remount_fs = unionfs_remount_fs,
9583+ .clear_inode = unionfs_clear_inode,
9584+ .umount_begin = unionfs_umount_begin,
9585+ .show_options = unionfs_show_options,
9586+ .write_inode = unionfs_write_inode,
9587+ .alloc_inode = unionfs_alloc_inode,
9588+ .destroy_inode = unionfs_destroy_inode,
9589+};
9590diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
9591new file mode 100644
9592index 0000000..1b9c3f7
9593--- /dev/null
9594+++ b/fs/unionfs/union.h
9595@@ -0,0 +1,607 @@
9596+/*
9597+ * Copyright (c) 2003-2008 Erez Zadok
9598+ * Copyright (c) 2003-2006 Charles P. Wright
9599+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
9600+ * Copyright (c) 2005 Arun M. Krishnakumar
9601+ * Copyright (c) 2004-2006 David P. Quigley
9602+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
9603+ * Copyright (c) 2003 Puja Gupta
9604+ * Copyright (c) 2003 Harikesavan Krishnan
9605+ * Copyright (c) 2003-2008 Stony Brook University
9606+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
9607+ *
9608+ * This program is free software; you can redistribute it and/or modify
9609+ * it under the terms of the GNU General Public License version 2 as
9610+ * published by the Free Software Foundation.
9611+ */
9612+
9613+#ifndef _UNION_H_
9614+#define _UNION_H_
9615+
9616+#include <linux/dcache.h>
9617+#include <linux/file.h>
9618+#include <linux/list.h>
9619+#include <linux/fs.h>
9620+#include <linux/mm.h>
9621+#include <linux/module.h>
9622+#include <linux/mount.h>
9623+#include <linux/namei.h>
9624+#include <linux/page-flags.h>
9625+#include <linux/pagemap.h>
9626+#include <linux/poll.h>
9627+#include <linux/security.h>
9628+#include <linux/seq_file.h>
9629+#include <linux/slab.h>
9630+#include <linux/spinlock.h>
9631+#include <linux/smp_lock.h>
9632+#include <linux/statfs.h>
9633+#include <linux/string.h>
9634+#include <linux/vmalloc.h>
9635+#include <linux/writeback.h>
9636+#include <linux/buffer_head.h>
9637+#include <linux/xattr.h>
9638+#include <linux/fs_stack.h>
9639+#include <linux/magic.h>
9640+#include <linux/log2.h>
9641+#include <linux/poison.h>
9642+#include <linux/mman.h>
9643+#include <linux/backing-dev.h>
9644+#include <linux/splice.h>
9645+
9646+#include <asm/system.h>
9647+
9648+#include <linux/union_fs.h>
9649+
9650+/* the file system name */
9651+#define UNIONFS_NAME "unionfs"
9652+
9653+/* unionfs root inode number */
9654+#define UNIONFS_ROOT_INO 1
9655+
9656+/* number of times we try to get a unique temporary file name */
9657+#define GET_TMPNAM_MAX_RETRY 5
9658+
9659+/* maximum number of branches we support, to avoid memory blowup */
9660+#define UNIONFS_MAX_BRANCHES 128
9661+
9662+/* minimum time (seconds) required for time-based cache-coherency */
9663+#define UNIONFS_MIN_CC_TIME 3
9664+
9665+/* Operations vectors defined in specific files. */
9666+extern struct file_operations unionfs_main_fops;
9667+extern struct file_operations unionfs_dir_fops;
9668+extern struct inode_operations unionfs_main_iops;
9669+extern struct inode_operations unionfs_dir_iops;
9670+extern struct inode_operations unionfs_symlink_iops;
9671+extern struct super_operations unionfs_sops;
9672+extern struct dentry_operations unionfs_dops;
9673+extern struct address_space_operations unionfs_aops, unionfs_dummy_aops;
9674+extern struct vm_operations_struct unionfs_vm_ops;
9675+
9676+/* How long should an entry be allowed to persist */
9677+#define RDCACHE_JIFFIES (5*HZ)
9678+
9679+/* compatibility with Real-Time patches */
9680+#ifdef CONFIG_PREEMPT_RT
9681+# define unionfs_rw_semaphore compat_rw_semaphore
9682+#else /* not CONFIG_PREEMPT_RT */
9683+# define unionfs_rw_semaphore rw_semaphore
9684+#endif /* not CONFIG_PREEMPT_RT */
9685+
9686+/* file private data. */
9687+struct unionfs_file_info {
9688+ int bstart;
9689+ int bend;
9690+ atomic_t generation;
9691+
9692+ struct unionfs_dir_state *rdstate;
9693+ struct file **lower_files;
9694+ int *saved_branch_ids; /* IDs of branches when file was opened */
9695+ struct vm_operations_struct *lower_vm_ops;
9696+ bool wrote_to_file; /* for delayed copyup */
9697+};
9698+
9699+/* unionfs inode data in memory */
9700+struct unionfs_inode_info {
9701+ int bstart;
9702+ int bend;
9703+ atomic_t generation;
9704+ /* Stuff for readdir over NFS. */
9705+ spinlock_t rdlock;
9706+ struct list_head readdircache;
9707+ int rdcount;
9708+ int hashsize;
9709+ int cookie;
9710+
9711+ /* The lower inodes */
9712+ struct inode **lower_inodes;
9713+
9714+ struct inode vfs_inode;
9715+};
9716+
9717+/* unionfs dentry data in memory */
9718+struct unionfs_dentry_info {
9719+ /*
9720+ * The semaphore is used to lock the dentry as soon as we get into a
9721+ * unionfs function from the VFS. Our lock ordering is that children
9722+ * go before their parents.
9723+ */
9724+ struct mutex lock;
9725+ int bstart;
9726+ int bend;
9727+ int bopaque;
9728+ int bcount;
9729+ atomic_t generation;
9730+ struct path *lower_paths;
9731+};
9732+
9733+/* These are the pointers to our various objects. */
9734+struct unionfs_data {
9735+ struct super_block *sb; /* lower super_block */
9736+ atomic_t open_files; /* number of open files on branch */
9737+ int branchperms;
9738+ int branch_id; /* unique branch ID at re/mount time */
9739+};
9740+
9741+/* unionfs super-block data in memory */
9742+struct unionfs_sb_info {
9743+ int bend;
9744+
9745+ atomic_t generation;
9746+
9747+ /*
9748+ * This rwsem is used to make sure that a branch management
9749+ * operation...
9750+ * 1) will not begin before all currently in-flight operations
9751+ * complete.
9752+ * 2) any new operations do not execute until the currently
9753+ * running branch management operation completes.
9754+ *
9755+ * The write_lock_owner records the PID of the task which grabbed
9756+ * the rw_sem for writing. If the same task also tries to grab the
9757+ * read lock, we allow it. This prevents a self-deadlock when
9758+ * branch-management is used on a pivot_root'ed union, because we
9759+ * have to ->lookup paths which belong to the same union.
9760+ */
9761+ struct unionfs_rw_semaphore rwsem;
9762+ pid_t write_lock_owner; /* PID of rw_sem owner (write lock) */
9763+ int high_branch_id; /* last unique branch ID given */
9764+ char *dev_name; /* to identify different unions in pr_debug */
9765+ struct unionfs_data *data;
9766+};
9767+
9768+/*
9769+ * structure for making the linked list of entries by readdir on left branch
9770+ * to compare with entries on right branch
9771+ */
9772+struct filldir_node {
9773+ struct list_head file_list; /* list for directory entries */
9774+ char *name; /* name entry */
9775+ int hash; /* name hash */
9776+ int namelen; /* name len since name is not 0 terminated */
9777+
9778+ /*
9779+ * we can check for duplicate whiteouts and files in the same branch
9780+ * in order to return -EIO.
9781+ */
9782+ int bindex;
9783+
9784+ /* is this a whiteout entry? */
9785+ int whiteout;
9786+
9787+ /* Inline name, so we don't need to separately kmalloc small ones */
9788+ char iname[DNAME_INLINE_LEN_MIN];
9789+};
9790+
9791+/* Directory hash table. */
9792+struct unionfs_dir_state {
9793+ unsigned int cookie; /* the cookie, based off of rdversion */
9794+ unsigned int offset; /* The entry we have returned. */
9795+ int bindex;
9796+ loff_t dirpos; /* offset within the lower level directory */
9797+ int size; /* How big is the hash table? */
9798+ int hashentries; /* How many entries have been inserted? */
9799+ unsigned long access;
9800+
9801+ /* This cache list is used when the inode keeps us around. */
9802+ struct list_head cache;
9803+ struct list_head list[0];
9804+};
9805+
9806+/* externs needed for fanout.h or sioq.h */
9807+extern int unionfs_get_nlinks(const struct inode *inode);
9808+extern void unionfs_copy_attr_times(struct inode *upper);
9809+extern void unionfs_copy_attr_all(struct inode *dest, const struct inode *src);
9810+
9811+/* include miscellaneous macros */
9812+#include "fanout.h"
9813+#include "sioq.h"
9814+
9815+/* externs for cache creation/deletion routines */
9816+extern void unionfs_destroy_filldir_cache(void);
9817+extern int unionfs_init_filldir_cache(void);
9818+extern int unionfs_init_inode_cache(void);
9819+extern void unionfs_destroy_inode_cache(void);
9820+extern int unionfs_init_dentry_cache(void);
9821+extern void unionfs_destroy_dentry_cache(void);
9822+
9823+/* Initialize and free readdir-specific state. */
9824+extern int init_rdstate(struct file *file);
9825+extern struct unionfs_dir_state *alloc_rdstate(struct inode *inode,
9826+ int bindex);
9827+extern struct unionfs_dir_state *find_rdstate(struct inode *inode,
9828+ loff_t fpos);
9829+extern void free_rdstate(struct unionfs_dir_state *state);
9830+extern int add_filldir_node(struct unionfs_dir_state *rdstate,
9831+ const char *name, int namelen, int bindex,
9832+ int whiteout);
9833+extern struct filldir_node *find_filldir_node(struct unionfs_dir_state *rdstate,
9834+ const char *name, int namelen,
9835+ int is_whiteout);
9836+
9837+extern struct dentry **alloc_new_dentries(int objs);
9838+extern struct unionfs_data *alloc_new_data(int objs);
9839+
9840+/* We can only use 32-bits of offset for rdstate --- blech! */
9841+#define DIREOF (0xfffff)
9842+#define RDOFFBITS 20 /* This is the number of bits in DIREOF. */
9843+#define MAXRDCOOKIE (0xfff)
9844+/* Turn an rdstate into an offset. */
9845+static inline off_t rdstate2offset(struct unionfs_dir_state *buf)
9846+{
9847+ off_t tmp;
9848+
9849+ tmp = ((buf->cookie & MAXRDCOOKIE) << RDOFFBITS)
9850+ | (buf->offset & DIREOF);
9851+ return tmp;
9852+}
9853+
9854+/* Macros for locking a super_block. */
9855+enum unionfs_super_lock_class {
9856+ UNIONFS_SMUTEX_NORMAL,
9857+ UNIONFS_SMUTEX_PARENT, /* when locking on behalf of file */
9858+ UNIONFS_SMUTEX_CHILD, /* when locking on behalf of dentry */
9859+};
9860+static inline void unionfs_read_lock(struct super_block *sb, int subclass)
9861+{
9862+ if (UNIONFS_SB(sb)->write_lock_owner &&
9863+ UNIONFS_SB(sb)->write_lock_owner == current->pid)
9864+ return;
9865+ down_read_nested(&UNIONFS_SB(sb)->rwsem, subclass);
9866+}
9867+static inline void unionfs_read_unlock(struct super_block *sb)
9868+{
9869+ if (UNIONFS_SB(sb)->write_lock_owner &&
9870+ UNIONFS_SB(sb)->write_lock_owner == current->pid)
9871+ return;
9872+ up_read(&UNIONFS_SB(sb)->rwsem);
9873+}
9874+static inline void unionfs_write_lock(struct super_block *sb)
9875+{
9876+ down_write(&UNIONFS_SB(sb)->rwsem);
9877+ UNIONFS_SB(sb)->write_lock_owner = current->pid;
9878+}
9879+static inline void unionfs_write_unlock(struct super_block *sb)
9880+{
9881+ up_write(&UNIONFS_SB(sb)->rwsem);
9882+ UNIONFS_SB(sb)->write_lock_owner = 0;
9883+}
9884+
9885+static inline void unionfs_double_lock_dentry(struct dentry *d1,
9886+ struct dentry *d2)
9887+{
9888+ BUG_ON(d1 == d2);
9889+ if (d1 < d2) {
9890+ unionfs_lock_dentry(d2, UNIONFS_DMUTEX_CHILD);
9891+ unionfs_lock_dentry(d1, UNIONFS_DMUTEX_PARENT);
9892+ } else {
9893+ unionfs_lock_dentry(d1, UNIONFS_DMUTEX_CHILD);
9894+ unionfs_lock_dentry(d2, UNIONFS_DMUTEX_PARENT);
9895+ }
9896+}
9897+
9898+extern int new_dentry_private_data(struct dentry *dentry, int subclass);
9899+extern int realloc_dentry_private_data(struct dentry *dentry);
9900+extern void free_dentry_private_data(struct dentry *dentry);
9901+extern void update_bstart(struct dentry *dentry);
9902+extern int init_lower_nd(struct nameidata *nd, unsigned int flags);
9903+extern void release_lower_nd(struct nameidata *nd, int err);
9904+
9905+/*
9906+ * EXTERNALS:
9907+ */
9908+
9909+/* replicates the directory structure up to given dentry in given branch */
9910+extern struct dentry *create_parents(struct inode *dir, struct dentry *dentry,
9911+ const char *name, int bindex);
9912+
9913+/* partial lookup */
9914+extern int unionfs_partial_lookup(struct dentry *dentry);
9915+extern struct dentry *unionfs_lookup_full(struct dentry *dentry,
9916+ struct nameidata *nd_unused,
9917+ int lookupmode);
9918+
9919+/* copies a file from dbstart to newbindex branch */
9920+extern int copyup_file(struct inode *dir, struct file *file, int bstart,
9921+ int newbindex, loff_t size);
9922+extern int copyup_named_file(struct inode *dir, struct file *file,
9923+ char *name, int bstart, int new_bindex,
9924+ loff_t len);
9925+/* copies a dentry from dbstart to newbindex branch */
9926+extern int copyup_dentry(struct inode *dir, struct dentry *dentry,
9927+ int bstart, int new_bindex, const char *name,
9928+ int namelen, struct file **copyup_file, loff_t len);
9929+/* helper functions for post-copyup actions */
9930+extern void unionfs_postcopyup_setmnt(struct dentry *dentry);
9931+extern void unionfs_postcopyup_release(struct dentry *dentry);
9932+
9933+/* Is this directory empty: 0 if it is empty, -ENOTEMPTY if not. */
9934+extern int check_empty(struct dentry *dentry,
9935+ struct unionfs_dir_state **namelist);
9936+/* whiteout and opaque directory helpers */
9937+extern char *alloc_whname(const char *name, int len);
9938+extern bool is_whiteout_name(char **namep, int *namelenp);
9939+extern bool is_validname(const char *name);
9940+extern struct dentry *lookup_whiteout(const char *name,
9941+ struct dentry *lower_parent);
9942+extern struct dentry *find_first_whiteout(struct dentry *dentry);
9943+extern int unlink_whiteout(struct dentry *wh_dentry);
9944+extern int check_unlink_whiteout(struct dentry *dentry,
9945+ struct dentry *lower_dentry, int bindex);
9946+extern int create_whiteout(struct dentry *dentry, int start);
9947+extern int delete_whiteouts(struct dentry *dentry, int bindex,
9948+ struct unionfs_dir_state *namelist);
9949+extern int is_opaque_dir(struct dentry *dentry, int bindex);
9950+extern int make_dir_opaque(struct dentry *dir, int bindex);
9951+extern void unionfs_set_max_namelen(long *namelen);
9952+
9953+extern void unionfs_reinterpose(struct dentry *this_dentry);
9954+extern struct super_block *unionfs_duplicate_super(struct super_block *sb);
9955+
9956+/* Locking functions. */
9957+extern int unionfs_setlk(struct file *file, int cmd, struct file_lock *fl);
9958+extern int unionfs_getlk(struct file *file, struct file_lock *fl);
9959+
9960+/* Common file operations. */
9961+extern int unionfs_file_revalidate(struct file *file, bool willwrite);
9962+extern int unionfs_file_revalidate_locked(struct file *file, bool willwrite);
9963+extern int unionfs_open(struct inode *inode, struct file *file);
9964+extern int unionfs_file_release(struct inode *inode, struct file *file);
9965+extern int unionfs_flush(struct file *file, fl_owner_t id);
9966+extern long unionfs_ioctl(struct file *file, unsigned int cmd,
9967+ unsigned long arg);
9968+extern int unionfs_fsync(struct file *file, struct dentry *dentry,
9969+ int datasync);
9970+extern int unionfs_fasync(int fd, struct file *file, int flag);
9971+
9972+/* Inode operations */
9973+extern struct inode *unionfs_iget(struct super_block *sb, unsigned long ino);
9974+extern int unionfs_rename(struct inode *old_dir, struct dentry *old_dentry,
9975+ struct inode *new_dir, struct dentry *new_dentry);
9976+extern int unionfs_unlink(struct inode *dir, struct dentry *dentry);
9977+extern int unionfs_rmdir(struct inode *dir, struct dentry *dentry);
9978+
9979+extern bool __unionfs_d_revalidate_one_locked(struct dentry *dentry,
9980+ struct nameidata *nd,
9981+ bool willwrite);
9982+extern bool __unionfs_d_revalidate_chain(struct dentry *dentry,
9983+ struct nameidata *nd, bool willwrite);
9984+extern bool is_negative_lower(const struct dentry *dentry);
9985+extern bool is_newer_lower(const struct dentry *dentry);
9986+extern void purge_sb_data(struct super_block *sb);
9987+
9988+/* The values for unionfs_interpose's flag. */
9989+#define INTERPOSE_DEFAULT 0
9990+#define INTERPOSE_LOOKUP 1
9991+#define INTERPOSE_REVAL 2
9992+#define INTERPOSE_REVAL_NEG 3
9993+#define INTERPOSE_PARTIAL 4
9994+
9995+extern struct dentry *unionfs_interpose(struct dentry *this_dentry,
9996+ struct super_block *sb, int flag);
9997+
9998+#ifdef CONFIG_UNION_FS_XATTR
9999+/* Extended attribute functions. */
10000+extern void *unionfs_xattr_alloc(size_t size, size_t limit);
10001+static inline void unionfs_xattr_kfree(const void *p)
10002+{
10003+ kfree(p);
10004+}
10005+extern ssize_t unionfs_getxattr(struct dentry *dentry, const char *name,
10006+ void *value, size_t size);
10007+extern int unionfs_removexattr(struct dentry *dentry, const char *name);
10008+extern ssize_t unionfs_listxattr(struct dentry *dentry, char *list,
10009+ size_t size);
10010+extern int unionfs_setxattr(struct dentry *dentry, const char *name,
10011+ const void *value, size_t size, int flags);
10012+#endif /* CONFIG_UNION_FS_XATTR */
10013+
10014+/* The root directory is unhashed, but isn't deleted. */
10015+static inline int d_deleted(struct dentry *d)
10016+{
10017+ return d_unhashed(d) && (d != d->d_sb->s_root);
10018+}
10019+
10020+/* unionfs_permission, check if we should bypass error to facilitate copyup */
10021+#define IS_COPYUP_ERR(err) ((err) == -EROFS)
10022+
10023+/* unionfs_open, check if we need to copyup the file */
10024+#define OPEN_WRITE_FLAGS (O_WRONLY | O_RDWR | O_APPEND)
10025+#define IS_WRITE_FLAG(flag) ((flag) & OPEN_WRITE_FLAGS)
10026+
10027+static inline int branchperms(const struct super_block *sb, int index)
10028+{
10029+ BUG_ON(index < 0);
10030+ return UNIONFS_SB(sb)->data[index].branchperms;
10031+}
10032+
10033+static inline int set_branchperms(struct super_block *sb, int index, int perms)
10034+{
10035+ BUG_ON(index < 0);
10036+ UNIONFS_SB(sb)->data[index].branchperms = perms;
10037+ return perms;
10038+}
10039+
10040+/* Is this file on a read-only branch? */
10041+static inline int is_robranch_super(const struct super_block *sb, int index)
10042+{
10043+ int ret;
10044+
10045+ ret = (!(branchperms(sb, index) & MAY_WRITE)) ? -EROFS : 0;
10046+ return ret;
10047+}
10048+
10049+/* Is this file on a read-only branch? */
10050+static inline int is_robranch_idx(const struct dentry *dentry, int index)
10051+{
10052+ struct super_block *lower_sb;
10053+
10054+ BUG_ON(index < 0);
10055+
10056+ if (!(branchperms(dentry->d_sb, index) & MAY_WRITE))
10057+ return -EROFS;
10058+
10059+ lower_sb = unionfs_lower_super_idx(dentry->d_sb, index);
10060+ BUG_ON(lower_sb == NULL);
10061+ /*
10062+ * test sb flags directly, not IS_RDONLY(lower_inode) because the
10063+ * lower_dentry could be a negative.
10064+ */
10065+ if (lower_sb->s_flags & MS_RDONLY)
10066+ return -EROFS;
10067+
10068+ return 0;
10069+}
10070+
10071+static inline int is_robranch(const struct dentry *dentry)
10072+{
10073+ int index;
10074+
10075+ index = UNIONFS_D(dentry)->bstart;
10076+ BUG_ON(index < 0);
10077+
10078+ return is_robranch_idx(dentry, index);
10079+}
10080+
10081+/*
10082+ * EXTERNALS:
10083+ */
10084+extern int check_branch(struct nameidata *nd);
10085+extern int parse_branch_mode(const char *name, int *perms);
10086+
10087+/* locking helpers */
10088+static inline struct dentry *lock_parent(struct dentry *dentry)
10089+{
10090+ struct dentry *dir = dget_parent(dentry);
10091+ mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
10092+ return dir;
10093+}
10094+static inline struct dentry *lock_parent_wh(struct dentry *dentry)
10095+{
10096+ struct dentry *dir = dget_parent(dentry);
10097+
10098+ mutex_lock_nested(&dir->d_inode->i_mutex, UNIONFS_DMUTEX_WHITEOUT);
10099+ return dir;
10100+}
10101+
10102+static inline void unlock_dir(struct dentry *dir)
10103+{
10104+ mutex_unlock(&dir->d_inode->i_mutex);
10105+ dput(dir);
10106+}
10107+
10108+static inline struct vfsmount *unionfs_mntget(struct dentry *dentry,
10109+ int bindex)
10110+{
10111+ struct vfsmount *mnt;
10112+
10113+ BUG_ON(!dentry || bindex < 0);
10114+
10115+ mnt = mntget(unionfs_lower_mnt_idx(dentry, bindex));
10116+#ifdef CONFIG_UNION_FS_DEBUG
10117+ if (!mnt)
10118+ pr_debug("unionfs: mntget: mnt=%p bindex=%d\n",
10119+ mnt, bindex);
10120+#endif /* CONFIG_UNION_FS_DEBUG */
10121+
10122+ return mnt;
10123+}
10124+
10125+static inline void unionfs_mntput(struct dentry *dentry, int bindex)
10126+{
10127+ struct vfsmount *mnt;
10128+
10129+ if (!dentry && bindex < 0)
10130+ return;
10131+ BUG_ON(!dentry || bindex < 0);
10132+
10133+ mnt = unionfs_lower_mnt_idx(dentry, bindex);
10134+#ifdef CONFIG_UNION_FS_DEBUG
10135+ /*
10136+ * Directories can have NULL lower objects in between start/end, but
10137+ * NOT if at the start/end range. We cannot verify that this dentry
10138+ * is a type=DIR, because it may already be a negative dentry. But
10139+ * if dbstart is greater than dbend, we know that this couldn't have
10140+ * been a regular file: it had to have been a directory.
10141+ */
10142+ if (!mnt && !(bindex > dbstart(dentry) && bindex < dbend(dentry)))
10143+ pr_debug("unionfs: mntput: mnt=%p bindex=%d\n", mnt, bindex);
10144+#endif /* CONFIG_UNION_FS_DEBUG */
10145+ mntput(mnt);
10146+}
10147+
10148+#ifdef CONFIG_UNION_FS_DEBUG
10149+
10150+/* useful for tracking code reachability */
10151+#define UDBG pr_debug("DBG:%s:%s:%d\n", __FILE__, __func__, __LINE__)
10152+
10153+#define unionfs_check_inode(i) __unionfs_check_inode((i), \
10154+ __FILE__, __func__, __LINE__)
10155+#define unionfs_check_dentry(d) __unionfs_check_dentry((d), \
10156+ __FILE__, __func__, __LINE__)
10157+#define unionfs_check_file(f) __unionfs_check_file((f), \
10158+ __FILE__, __func__, __LINE__)
10159+#define unionfs_check_nd(n) __unionfs_check_nd((n), \
10160+ __FILE__, __func__, __LINE__)
10161+#define show_branch_counts(sb) __show_branch_counts((sb), \
10162+ __FILE__, __func__, __LINE__)
10163+#define show_inode_times(i) __show_inode_times((i), \
10164+ __FILE__, __func__, __LINE__)
10165+#define show_dinode_times(d) __show_dinode_times((d), \
10166+ __FILE__, __func__, __LINE__)
10167+#define show_inode_counts(i) __show_inode_counts((i), \
10168+ __FILE__, __func__, __LINE__)
10169+
10170+extern void __unionfs_check_inode(const struct inode *inode, const char *fname,
10171+ const char *fxn, int line);
10172+extern void __unionfs_check_dentry(const struct dentry *dentry,
10173+ const char *fname, const char *fxn,
10174+ int line);
10175+extern void __unionfs_check_file(const struct file *file,
10176+ const char *fname, const char *fxn, int line);
10177+extern void __unionfs_check_nd(const struct nameidata *nd,
10178+ const char *fname, const char *fxn, int line);
10179+extern void __show_branch_counts(const struct super_block *sb,
10180+ const char *file, const char *fxn, int line);
10181+extern void __show_inode_times(const struct inode *inode,
10182+ const char *file, const char *fxn, int line);
10183+extern void __show_dinode_times(const struct dentry *dentry,
10184+ const char *file, const char *fxn, int line);
10185+extern void __show_inode_counts(const struct inode *inode,
10186+ const char *file, const char *fxn, int line);
10187+
10188+#else /* not CONFIG_UNION_FS_DEBUG */
10189+
10190+/* we leave useful hooks for these check functions throughout the code */
10191+#define unionfs_check_inode(i) do { } while (0)
10192+#define unionfs_check_dentry(d) do { } while (0)
10193+#define unionfs_check_file(f) do { } while (0)
10194+#define unionfs_check_nd(n) do { } while (0)
10195+#define show_branch_counts(sb) do { } while (0)
10196+#define show_inode_times(i) do { } while (0)
10197+#define show_dinode_times(d) do { } while (0)
10198+#define show_inode_counts(i) do { } while (0)
10199+
10200+#endif /* not CONFIG_UNION_FS_DEBUG */
10201+
10202+#endif /* not _UNION_H_ */
10203diff --git a/fs/unionfs/unlink.c b/fs/unionfs/unlink.c
10204new file mode 100644
10205index 0000000..623f68d
10206--- /dev/null
10207+++ b/fs/unionfs/unlink.c
10208@@ -0,0 +1,277 @@
10209+/*
10210+ * Copyright (c) 2003-2008 Erez Zadok
10211+ * Copyright (c) 2003-2006 Charles P. Wright
10212+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
10213+ * Copyright (c) 2005-2006 Junjiro Okajima
10214+ * Copyright (c) 2005 Arun M. Krishnakumar
10215+ * Copyright (c) 2004-2006 David P. Quigley
10216+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
10217+ * Copyright (c) 2003 Puja Gupta
10218+ * Copyright (c) 2003 Harikesavan Krishnan
10219+ * Copyright (c) 2003-2008 Stony Brook University
10220+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
10221+ *
10222+ * This program is free software; you can redistribute it and/or modify
10223+ * it under the terms of the GNU General Public License version 2 as
10224+ * published by the Free Software Foundation.
10225+ */
10226+
10227+#include "union.h"
10228+
10229+/*
10230+ * Helper function for Unionfs's unlink operation.
10231+ *
10232+ * The main goal of this function is to optimize the unlinking of non-dir
10233+ * objects in unionfs by deleting all possible lower inode objects from the
10234+ * underlying branches having same dentry name as the non-dir dentry on
10235+ * which this unlink operation is called. This way we delete as many lower
10236+ * inodes as possible, and save space. Whiteouts need to be created in
10237+ * branch0 only if unlinking fails on any of the lower branch other than
10238+ * branch0, or if a lower branch is marked read-only.
10239+ *
10240+ * Also, while unlinking a file, if we encounter any dir type entry in any
10241+ * intermediate branch, then we remove the directory by calling vfs_rmdir.
10242+ * The following special cases are also handled:
10243+
10244+ * (1) If an error occurs in branch0 during vfs_unlink, then we return
10245+ * appropriate error.
10246+ *
10247+ * (2) If we get an error during unlink in any of other lower branch other
10248+ * than branch0, then we create a whiteout in branch0.
10249+ *
10250+ * (3) If a whiteout already exists in any intermediate branch, we delete
10251+ * all possible inodes only up to that branch (this is an "opaqueness"
10252+ * as as per Documentation/filesystems/unionfs/concepts.txt).
10253+ *
10254+ */
10255+static int unionfs_unlink_whiteout(struct inode *dir, struct dentry *dentry)
10256+{
10257+ struct dentry *lower_dentry;
10258+ struct dentry *lower_dir_dentry;
10259+ int bindex;
10260+ int err = 0;
10261+
10262+ err = unionfs_partial_lookup(dentry);
10263+ if (err)
10264+ goto out;
10265+
10266+ /* trying to unlink all possible valid instances */
10267+ for (bindex = dbstart(dentry); bindex <= dbend(dentry); bindex++) {
10268+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
10269+ if (!lower_dentry || !lower_dentry->d_inode)
10270+ continue;
10271+
10272+ lower_dir_dentry = lock_parent(lower_dentry);
10273+
10274+ /* avoid destroying the lower inode if the object is in use */
10275+ dget(lower_dentry);
10276+ err = is_robranch_super(dentry->d_sb, bindex);
10277+ if (!err) {
10278+ /* see Documentation/filesystems/unionfs/issues.txt */
10279+ lockdep_off();
10280+ if (!S_ISDIR(lower_dentry->d_inode->i_mode))
10281+ err = vfs_unlink(lower_dir_dentry->d_inode,
10282+ lower_dentry);
10283+ else
10284+ err = vfs_rmdir(lower_dir_dentry->d_inode,
10285+ lower_dentry);
10286+ lockdep_on();
10287+ }
10288+
10289+ /* if lower object deletion succeeds, update inode's times */
10290+ if (!err)
10291+ unionfs_copy_attr_times(dentry->d_inode);
10292+ dput(lower_dentry);
10293+ fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
10294+ unlock_dir(lower_dir_dentry);
10295+
10296+ if (err)
10297+ break;
10298+ }
10299+
10300+ /*
10301+ * Create the whiteout in branch 0 (highest priority) only if (a)
10302+ * there was an error in any intermediate branch other than branch 0
10303+ * due to failure of vfs_unlink/vfs_rmdir or (b) a branch marked or
10304+ * mounted read-only.
10305+ */
10306+ if (err) {
10307+ if ((bindex == 0) ||
10308+ ((bindex == dbstart(dentry)) &&
10309+ (!IS_COPYUP_ERR(err))))
10310+ goto out;
10311+ else {
10312+ if (!IS_COPYUP_ERR(err))
10313+ pr_debug("unionfs: lower object deletion "
10314+ "failed in branch:%d\n", bindex);
10315+ err = create_whiteout(dentry, sbstart(dentry->d_sb));
10316+ }
10317+ }
10318+
10319+out:
10320+ if (!err)
10321+ inode_dec_link_count(dentry->d_inode);
10322+
10323+ /* We don't want to leave negative leftover dentries for revalidate. */
10324+ if (!err && (dbopaque(dentry) != -1))
10325+ update_bstart(dentry);
10326+
10327+ return err;
10328+}
10329+
10330+int unionfs_unlink(struct inode *dir, struct dentry *dentry)
10331+{
10332+ int err = 0;
10333+ struct inode *inode = dentry->d_inode;
10334+ int valid;
10335+
10336+ BUG_ON(S_ISDIR(inode->i_mode));
10337+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
10338+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
10339+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT);
10340+
10341+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, NULL, false);
10342+ if (unlikely(!valid)) {
10343+ err = -ESTALE;
10344+ goto out;
10345+ }
10346+ valid = __unionfs_d_revalidate_one_locked(dentry, NULL, false);
10347+ if (unlikely(!valid)) {
10348+ err = -ESTALE;
10349+ goto out;
10350+ }
10351+ unionfs_check_dentry(dentry);
10352+
10353+ err = unionfs_unlink_whiteout(dir, dentry);
10354+ /* call d_drop so the system "forgets" about us */
10355+ if (!err) {
10356+ unionfs_postcopyup_release(dentry);
10357+ if (inode->i_nlink == 0) /* drop lower inodes */
10358+ iput_lowers_all(inode, false);
10359+ d_drop(dentry);
10360+ /*
10361+ * if unlink/whiteout succeeded, parent dir mtime has
10362+ * changed
10363+ */
10364+ unionfs_copy_attr_times(dir);
10365+ }
10366+
10367+out:
10368+ if (!err) {
10369+ unionfs_check_dentry(dentry);
10370+ unionfs_check_inode(dir);
10371+ }
10372+ unionfs_unlock_dentry(dentry->d_parent);
10373+ unionfs_unlock_dentry(dentry);
10374+ unionfs_read_unlock(dentry->d_sb);
10375+ return err;
10376+}
10377+
10378+static int unionfs_rmdir_first(struct inode *dir, struct dentry *dentry,
10379+ struct unionfs_dir_state *namelist)
10380+{
10381+ int err;
10382+ struct dentry *lower_dentry;
10383+ struct dentry *lower_dir_dentry = NULL;
10384+
10385+ /* Here we need to remove whiteout entries. */
10386+ err = delete_whiteouts(dentry, dbstart(dentry), namelist);
10387+ if (err)
10388+ goto out;
10389+
10390+ lower_dentry = unionfs_lower_dentry(dentry);
10391+
10392+ lower_dir_dentry = lock_parent(lower_dentry);
10393+
10394+ /* avoid destroying the lower inode if the file is in use */
10395+ dget(lower_dentry);
10396+ err = is_robranch(dentry);
10397+ if (!err) {
10398+ /* see Documentation/filesystems/unionfs/issues.txt */
10399+ lockdep_off();
10400+ err = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
10401+ lockdep_on();
10402+ }
10403+ dput(lower_dentry);
10404+
10405+ fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
10406+ /* propagate number of hard-links */
10407+ dentry->d_inode->i_nlink = unionfs_get_nlinks(dentry->d_inode);
10408+
10409+out:
10410+ if (lower_dir_dentry)
10411+ unlock_dir(lower_dir_dentry);
10412+ return err;
10413+}
10414+
10415+int unionfs_rmdir(struct inode *dir, struct dentry *dentry)
10416+{
10417+ int err = 0;
10418+ struct unionfs_dir_state *namelist = NULL;
10419+ int dstart, dend;
10420+
10421+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
10422+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
10423+
10424+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
10425+ err = -ESTALE;
10426+ goto out;
10427+ }
10428+ unionfs_check_dentry(dentry);
10429+
10430+ /* check if this unionfs directory is empty or not */
10431+ err = check_empty(dentry, &namelist);
10432+ if (err)
10433+ goto out;
10434+
10435+ err = unionfs_rmdir_first(dir, dentry, namelist);
10436+ dstart = dbstart(dentry);
10437+ dend = dbend(dentry);
10438+ /*
10439+ * We create a whiteout for the directory if there was an error to
10440+ * rmdir the first directory entry in the union. Otherwise, we
10441+ * create a whiteout only if there is no chance that a lower
10442+ * priority branch might also have the same named directory. IOW,
10443+ * if there is not another same-named directory at a lower priority
10444+ * branch, then we don't need to create a whiteout for it.
10445+ */
10446+ if (!err) {
10447+ if (dstart < dend)
10448+ err = create_whiteout(dentry, dstart);
10449+ } else {
10450+ int new_err;
10451+
10452+ if (dstart == 0)
10453+ goto out;
10454+
10455+ /* exit if the error returned was NOT -EROFS */
10456+ if (!IS_COPYUP_ERR(err))
10457+ goto out;
10458+
10459+ new_err = create_whiteout(dentry, dstart - 1);
10460+ if (new_err != -EEXIST)
10461+ err = new_err;
10462+ }
10463+
10464+out:
10465+ /*
10466+ * Drop references to lower dentry/inode so storage space for them
10467+ * can be reclaimed. Then, call d_drop so the system "forgets"
10468+ * about us.
10469+ */
10470+ if (!err) {
10471+ iput_lowers_all(dentry->d_inode, false);
10472+ dput(unionfs_lower_dentry_idx(dentry, dstart));
10473+ unionfs_set_lower_dentry_idx(dentry, dstart, NULL);
10474+ d_drop(dentry);
10475+ /* update our lower vfsmnts, in case a copyup took place */
10476+ unionfs_postcopyup_setmnt(dentry);
10477+ }
10478+
10479+ if (namelist)
10480+ free_rdstate(namelist);
10481+
10482+ unionfs_unlock_dentry(dentry);
10483+ unionfs_read_unlock(dentry->d_sb);
10484+ return err;
10485+}
10486diff --git a/fs/unionfs/whiteout.c b/fs/unionfs/whiteout.c
10487new file mode 100644
10488index 0000000..db7a21e
10489--- /dev/null
10490+++ b/fs/unionfs/whiteout.c
10491@@ -0,0 +1,577 @@
10492+/*
10493+ * Copyright (c) 2003-2008 Erez Zadok
10494+ * Copyright (c) 2003-2006 Charles P. Wright
10495+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
10496+ * Copyright (c) 2005-2006 Junjiro Okajima
10497+ * Copyright (c) 2005 Arun M. Krishnakumar
10498+ * Copyright (c) 2004-2006 David P. Quigley
10499+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
10500+ * Copyright (c) 2003 Puja Gupta
10501+ * Copyright (c) 2003 Harikesavan Krishnan
10502+ * Copyright (c) 2003-2008 Stony Brook University
10503+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
10504+ *
10505+ * This program is free software; you can redistribute it and/or modify
10506+ * it under the terms of the GNU General Public License version 2 as
10507+ * published by the Free Software Foundation.
10508+ */
10509+
10510+#include "union.h"
10511+
10512+/*
10513+ * whiteout and opaque directory helpers
10514+ */
10515+
10516+/* What do we use for whiteouts. */
10517+#define UNIONFS_WHPFX ".wh."
10518+#define UNIONFS_WHLEN 4
10519+/*
10520+ * If a directory contains this file, then it is opaque. We start with the
10521+ * .wh. flag so that it is blocked by lookup.
10522+ */
10523+#define UNIONFS_DIR_OPAQUE_NAME "__dir_opaque"
10524+#define UNIONFS_DIR_OPAQUE UNIONFS_WHPFX UNIONFS_DIR_OPAQUE_NAME
10525+
10526+/* construct whiteout filename */
10527+char *alloc_whname(const char *name, int len)
10528+{
10529+ char *buf;
10530+
10531+ buf = kmalloc(len + UNIONFS_WHLEN + 1, GFP_KERNEL);
10532+ if (unlikely(!buf))
10533+ return ERR_PTR(-ENOMEM);
10534+
10535+ strcpy(buf, UNIONFS_WHPFX);
10536+ strlcat(buf, name, len + UNIONFS_WHLEN + 1);
10537+
10538+ return buf;
10539+}
10540+
10541+/*
10542+ * XXX: this can be inline or CPP macro, but is here to keep all whiteout
10543+ * code in one place.
10544+ */
10545+void unionfs_set_max_namelen(long *namelen)
10546+{
10547+ *namelen -= UNIONFS_WHLEN;
10548+}
10549+
10550+/* check if @namep is a whiteout, update @namep and @namelenp accordingly */
10551+bool is_whiteout_name(char **namep, int *namelenp)
10552+{
10553+ if (*namelenp > UNIONFS_WHLEN &&
10554+ !strncmp(*namep, UNIONFS_WHPFX, UNIONFS_WHLEN)) {
10555+ *namep += UNIONFS_WHLEN;
10556+ *namelenp -= UNIONFS_WHLEN;
10557+ return true;
10558+ }
10559+ return false;
10560+}
10561+
10562+/* is the filename valid == !(whiteout for a file or opaque dir marker) */
10563+bool is_validname(const char *name)
10564+{
10565+ if (!strncmp(name, UNIONFS_WHPFX, UNIONFS_WHLEN))
10566+ return false;
10567+ if (!strncmp(name, UNIONFS_DIR_OPAQUE_NAME,
10568+ sizeof(UNIONFS_DIR_OPAQUE_NAME) - 1))
10569+ return false;
10570+ return true;
10571+}
10572+
10573+/*
10574+ * Look for a whiteout @name in @lower_parent directory. If error, return
10575+ * ERR_PTR. Caller must dput() the returned dentry if not an error.
10576+ *
10577+ * XXX: some callers can reuse the whname allocated buffer to avoid repeated
10578+ * free then re-malloc calls. Need to provide a different API for those
10579+ * callers.
10580+ */
10581+struct dentry *lookup_whiteout(const char *name, struct dentry *lower_parent)
10582+{
10583+ char *whname = NULL;
10584+ int err = 0, namelen;
10585+ struct dentry *wh_dentry = NULL;
10586+
10587+ namelen = strlen(name);
10588+ whname = alloc_whname(name, namelen);
10589+ if (unlikely(IS_ERR(whname))) {
10590+ err = PTR_ERR(whname);
10591+ goto out;
10592+ }
10593+
10594+ /* check if whiteout exists in this branch: lookup .wh.foo */
10595+ wh_dentry = lookup_one_len(whname, lower_parent, strlen(whname));
10596+ if (IS_ERR(wh_dentry)) {
10597+ err = PTR_ERR(wh_dentry);
10598+ goto out;
10599+ }
10600+
10601+ /* check if negative dentry (ENOENT) */
10602+ if (!wh_dentry->d_inode)
10603+ goto out;
10604+
10605+ /* whiteout found: check if valid type */
10606+ if (!S_ISREG(wh_dentry->d_inode->i_mode)) {
10607+ printk(KERN_ERR "unionfs: invalid whiteout %s entry type %d\n",
10608+ whname, wh_dentry->d_inode->i_mode);
10609+ dput(wh_dentry);
10610+ err = -EIO;
10611+ goto out;
10612+ }
10613+
10614+out:
10615+ kfree(whname);
10616+ if (err)
10617+ wh_dentry = ERR_PTR(err);
10618+ return wh_dentry;
10619+}
10620+
10621+/* find and return first whiteout in parent directory, else ENOENT */
10622+struct dentry *find_first_whiteout(struct dentry *dentry)
10623+{
10624+ int bindex, bstart, bend;
10625+ struct dentry *parent, *lower_parent, *wh_dentry;
10626+
10627+ parent = dget_parent(dentry);
10628+ unionfs_lock_dentry(parent, UNIONFS_DMUTEX_WHITEOUT);
10629+ bstart = dbstart(parent);
10630+ bend = dbend(parent);
10631+ wh_dentry = ERR_PTR(-ENOENT);
10632+
10633+ for (bindex = bstart; bindex <= bend; bindex++) {
10634+ lower_parent = unionfs_lower_dentry_idx(parent, bindex);
10635+ if (!lower_parent)
10636+ continue;
10637+ wh_dentry = lookup_whiteout(dentry->d_name.name, lower_parent);
10638+ if (IS_ERR(wh_dentry))
10639+ continue;
10640+ if (wh_dentry->d_inode)
10641+ break;
10642+ dput(wh_dentry);
10643+ wh_dentry = ERR_PTR(-ENOENT);
10644+ }
10645+ unionfs_unlock_dentry(parent);
10646+ dput(parent);
10647+
10648+ return wh_dentry;
10649+}
10650+
10651+/*
10652+ * Unlink a whiteout dentry. Returns 0 or -errno. Caller must hold and
10653+ * release dentry reference.
10654+ */
10655+int unlink_whiteout(struct dentry *wh_dentry)
10656+{
10657+ int err;
10658+ struct dentry *lower_dir_dentry;
10659+
10660+ /* dget and lock parent dentry */
10661+ lower_dir_dentry = lock_parent_wh(wh_dentry);
10662+
10663+ /* see Documentation/filesystems/unionfs/issues.txt */
10664+ lockdep_off();
10665+ err = vfs_unlink(lower_dir_dentry->d_inode, wh_dentry);
10666+ lockdep_on();
10667+ unlock_dir(lower_dir_dentry);
10668+
10669+ /*
10670+ * Whiteouts are special files and should be deleted no matter what
10671+ * (as if they never existed), in order to allow this create
10672+ * operation to succeed. This is especially important in sticky
10673+ * directories: a whiteout may have been created by one user, but
10674+ * the newly created file may be created by another user.
10675+ * Therefore, in order to maintain Unix semantics, if the vfs_unlink
10676+ * above failed, then we have to try to directly unlink the
10677+ * whiteout. Note: in the ODF version of unionfs, whiteout are
10678+ * handled much more cleanly.
10679+ */
10680+ if (err == -EPERM) {
10681+ struct inode *inode = lower_dir_dentry->d_inode;
10682+ err = inode->i_op->unlink(inode, wh_dentry);
10683+ }
10684+ if (err)
10685+ printk(KERN_ERR "unionfs: could not unlink whiteout %s, "
10686+ "err = %d\n", wh_dentry->d_name.name, err);
10687+
10688+ return err;
10689+
10690+}
10691+
10692+/*
10693+ * Helper function when creating new objects (create, symlink, mknod, etc.).
10694+ * Checks to see if there's a whiteout in @lower_dentry's parent directory,
10695+ * whose name is taken from @dentry. Then tries to remove that whiteout, if
10696+ * found. If <dentry,bindex> is a branch marked readonly, return -EROFS.
10697+ * If it finds both a regular file and a whiteout, return -EIO (this should
10698+ * never happen).
10699+ *
10700+ * Return 0 if no whiteout was found. Return 1 if one was found and
10701+ * successfully removed. Therefore a value >= 0 tells the caller that
10702+ * @lower_dentry belongs to a good branch to create the new object in).
10703+ * Return -ERRNO if an error occurred during whiteout lookup or in trying to
10704+ * unlink the whiteout.
10705+ */
10706+int check_unlink_whiteout(struct dentry *dentry, struct dentry *lower_dentry,
10707+ int bindex)
10708+{
10709+ int err;
10710+ struct dentry *wh_dentry = NULL;
10711+ struct dentry *lower_dir_dentry = NULL;
10712+
10713+ /* look for whiteout dentry first */
10714+ lower_dir_dentry = dget_parent(lower_dentry);
10715+ wh_dentry = lookup_whiteout(dentry->d_name.name, lower_dir_dentry);
10716+ dput(lower_dir_dentry);
10717+ if (IS_ERR(wh_dentry)) {
10718+ err = PTR_ERR(wh_dentry);
10719+ goto out;
10720+ }
10721+
10722+ if (!wh_dentry->d_inode) { /* no whiteout exists*/
10723+ err = 0;
10724+ goto out_dput;
10725+ }
10726+
10727+ /* check if regular file and whiteout were both found */
10728+ if (unlikely(lower_dentry->d_inode)) {
10729+ err = -EIO;
10730+ printk(KERN_ERR "unionfs: found both whiteout and regular "
10731+ "file in directory %s (branch %d)\n",
10732+ lower_dentry->d_parent->d_name.name, bindex);
10733+ goto out_dput;
10734+ }
10735+
10736+ /* check if branch is writeable */
10737+ err = is_robranch_super(dentry->d_sb, bindex);
10738+ if (err)
10739+ goto out_dput;
10740+
10741+ /* .wh.foo has been found, so let's unlink it */
10742+ err = unlink_whiteout(wh_dentry);
10743+ if (!err)
10744+ err = 1; /* a whiteout was found and successfully removed */
10745+out_dput:
10746+ dput(wh_dentry);
10747+out:
10748+ return err;
10749+}
10750+
10751+/*
10752+ * Pass an unionfs dentry and an index. It will try to create a whiteout
10753+ * for the filename in dentry, and will try in branch 'index'. On error,
10754+ * it will proceed to a branch to the left.
10755+ */
10756+int create_whiteout(struct dentry *dentry, int start)
10757+{
10758+ int bstart, bend, bindex;
10759+ struct dentry *lower_dir_dentry;
10760+ struct dentry *lower_dentry;
10761+ struct dentry *lower_wh_dentry;
10762+ struct nameidata nd;
10763+ char *name = NULL;
10764+ int err = -EINVAL;
10765+
10766+ verify_locked(dentry);
10767+
10768+ bstart = dbstart(dentry);
10769+ bend = dbend(dentry);
10770+
10771+ /* create dentry's whiteout equivalent */
10772+ name = alloc_whname(dentry->d_name.name, dentry->d_name.len);
10773+ if (unlikely(IS_ERR(name))) {
10774+ err = PTR_ERR(name);
10775+ goto out;
10776+ }
10777+
10778+ for (bindex = start; bindex >= 0; bindex--) {
10779+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
10780+
10781+ if (!lower_dentry) {
10782+ /*
10783+ * if lower dentry is not present, create the
10784+ * entire lower dentry directory structure and go
10785+ * ahead. Since we want to just create whiteout, we
10786+ * only want the parent dentry, and hence get rid of
10787+ * this dentry.
10788+ */
10789+ lower_dentry = create_parents(dentry->d_inode,
10790+ dentry,
10791+ dentry->d_name.name,
10792+ bindex);
10793+ if (!lower_dentry || IS_ERR(lower_dentry)) {
10794+ int ret = PTR_ERR(lower_dentry);
10795+ if (!IS_COPYUP_ERR(ret))
10796+ printk(KERN_ERR
10797+ "unionfs: create_parents for "
10798+ "whiteout failed: bindex=%d "
10799+ "err=%d\n", bindex, ret);
10800+ continue;
10801+ }
10802+ }
10803+
10804+ lower_wh_dentry =
10805+ lookup_one_len(name, lower_dentry->d_parent,
10806+ dentry->d_name.len + UNIONFS_WHLEN);
10807+ if (IS_ERR(lower_wh_dentry))
10808+ continue;
10809+
10810+ /*
10811+ * The whiteout already exists. This used to be impossible,
10812+ * but now is possible because of opaqueness.
10813+ */
10814+ if (lower_wh_dentry->d_inode) {
10815+ dput(lower_wh_dentry);
10816+ err = 0;
10817+ goto out;
10818+ }
10819+
10820+ err = init_lower_nd(&nd, LOOKUP_CREATE);
10821+ if (unlikely(err < 0))
10822+ goto out;
10823+ lower_dir_dentry = lock_parent_wh(lower_wh_dentry);
10824+ err = is_robranch_super(dentry->d_sb, bindex);
10825+ if (!err)
10826+ err = vfs_create(lower_dir_dentry->d_inode,
10827+ lower_wh_dentry,
10828+ ~current->fs->umask & S_IRUGO,
10829+ &nd);
10830+ unlock_dir(lower_dir_dentry);
10831+ dput(lower_wh_dentry);
10832+ release_lower_nd(&nd, err);
10833+
10834+ if (!err || !IS_COPYUP_ERR(err))
10835+ break;
10836+ }
10837+
10838+ /* set dbopaque so that lookup will not proceed after this branch */
10839+ if (!err)
10840+ dbopaque(dentry) = bindex;
10841+
10842+out:
10843+ kfree(name);
10844+ return err;
10845+}
10846+
10847+/*
10848+ * Delete all of the whiteouts in a given directory for rmdir.
10849+ *
10850+ * lower directory inode should be locked
10851+ */
10852+static int do_delete_whiteouts(struct dentry *dentry, int bindex,
10853+ struct unionfs_dir_state *namelist)
10854+{
10855+ int err = 0;
10856+ struct dentry *lower_dir_dentry = NULL;
10857+ struct dentry *lower_dentry;
10858+ char *name = NULL, *p;
10859+ struct inode *lower_dir;
10860+ int i;
10861+ struct list_head *pos;
10862+ struct filldir_node *cursor;
10863+
10864+ /* Find out lower parent dentry */
10865+ lower_dir_dentry = unionfs_lower_dentry_idx(dentry, bindex);
10866+ BUG_ON(!S_ISDIR(lower_dir_dentry->d_inode->i_mode));
10867+ lower_dir = lower_dir_dentry->d_inode;
10868+ BUG_ON(!S_ISDIR(lower_dir->i_mode));
10869+
10870+ err = -ENOMEM;
10871+ name = __getname();
10872+ if (unlikely(!name))
10873+ goto out;
10874+ strcpy(name, UNIONFS_WHPFX);
10875+ p = name + UNIONFS_WHLEN;
10876+
10877+ err = 0;
10878+ for (i = 0; !err && i < namelist->size; i++) {
10879+ list_for_each(pos, &namelist->list[i]) {
10880+ cursor =
10881+ list_entry(pos, struct filldir_node,
10882+ file_list);
10883+ /* Only operate on whiteouts in this branch. */
10884+ if (cursor->bindex != bindex)
10885+ continue;
10886+ if (!cursor->whiteout)
10887+ continue;
10888+
10889+ strlcpy(p, cursor->name, PATH_MAX - UNIONFS_WHLEN);
10890+ lower_dentry =
10891+ lookup_one_len(name, lower_dir_dentry,
10892+ cursor->namelen +
10893+ UNIONFS_WHLEN);
10894+ if (IS_ERR(lower_dentry)) {
10895+ err = PTR_ERR(lower_dentry);
10896+ break;
10897+ }
10898+ if (lower_dentry->d_inode)
10899+ err = vfs_unlink(lower_dir, lower_dentry);
10900+ dput(lower_dentry);
10901+ if (err)
10902+ break;
10903+ }
10904+ }
10905+
10906+ __putname(name);
10907+
10908+ /* After all of the removals, we should copy the attributes once. */
10909+ fsstack_copy_attr_times(dentry->d_inode, lower_dir_dentry->d_inode);
10910+
10911+out:
10912+ return err;
10913+}
10914+
10915+
10916+void __delete_whiteouts(struct work_struct *work)
10917+{
10918+ struct sioq_args *args = container_of(work, struct sioq_args, work);
10919+ struct deletewh_args *d = &args->deletewh;
10920+
10921+ args->err = do_delete_whiteouts(d->dentry, d->bindex, d->namelist);
10922+ complete(&args->comp);
10923+}
10924+
10925+/* delete whiteouts in a dir (for rmdir operation) using sioq if necessary */
10926+int delete_whiteouts(struct dentry *dentry, int bindex,
10927+ struct unionfs_dir_state *namelist)
10928+{
10929+ int err;
10930+ struct super_block *sb;
10931+ struct dentry *lower_dir_dentry;
10932+ struct inode *lower_dir;
10933+ struct sioq_args args;
10934+
10935+ sb = dentry->d_sb;
10936+
10937+ BUG_ON(!S_ISDIR(dentry->d_inode->i_mode));
10938+ BUG_ON(bindex < dbstart(dentry));
10939+ BUG_ON(bindex > dbend(dentry));
10940+ err = is_robranch_super(sb, bindex);
10941+ if (err)
10942+ goto out;
10943+
10944+ lower_dir_dentry = unionfs_lower_dentry_idx(dentry, bindex);
10945+ BUG_ON(!S_ISDIR(lower_dir_dentry->d_inode->i_mode));
10946+ lower_dir = lower_dir_dentry->d_inode;
10947+ BUG_ON(!S_ISDIR(lower_dir->i_mode));
10948+
10949+ if (!inode_permission(lower_dir, MAY_WRITE | MAY_EXEC)) {
10950+ err = do_delete_whiteouts(dentry, bindex, namelist);
10951+ } else {
10952+ args.deletewh.namelist = namelist;
10953+ args.deletewh.dentry = dentry;
10954+ args.deletewh.bindex = bindex;
10955+ run_sioq(__delete_whiteouts, &args);
10956+ err = args.err;
10957+ }
10958+
10959+out:
10960+ return err;
10961+}
10962+
10963+/****************************************************************************
10964+ * Opaque directory helpers *
10965+ ****************************************************************************/
10966+
10967+/*
10968+ * is_opaque_dir: returns 0 if it is NOT an opaque dir, 1 if it is, and
10969+ * -errno if an error occurred trying to figure this out.
10970+ */
10971+int is_opaque_dir(struct dentry *dentry, int bindex)
10972+{
10973+ int err = 0;
10974+ struct dentry *lower_dentry;
10975+ struct dentry *wh_lower_dentry;
10976+ struct inode *lower_inode;
10977+ struct sioq_args args;
10978+
10979+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
10980+ lower_inode = lower_dentry->d_inode;
10981+
10982+ BUG_ON(!S_ISDIR(lower_inode->i_mode));
10983+
10984+ mutex_lock(&lower_inode->i_mutex);
10985+
10986+ if (!inode_permission(lower_inode, MAY_EXEC)) {
10987+ wh_lower_dentry =
10988+ lookup_one_len(UNIONFS_DIR_OPAQUE, lower_dentry,
10989+ sizeof(UNIONFS_DIR_OPAQUE) - 1);
10990+ } else {
10991+ args.is_opaque.dentry = lower_dentry;
10992+ run_sioq(__is_opaque_dir, &args);
10993+ wh_lower_dentry = args.ret;
10994+ }
10995+
10996+ mutex_unlock(&lower_inode->i_mutex);
10997+
10998+ if (IS_ERR(wh_lower_dentry)) {
10999+ err = PTR_ERR(wh_lower_dentry);
11000+ goto out;
11001+ }
11002+
11003+ /* This is an opaque dir iff wh_lower_dentry is positive */
11004+ err = !!wh_lower_dentry->d_inode;
11005+
11006+ dput(wh_lower_dentry);
11007+out:
11008+ return err;
11009+}
11010+
11011+void __is_opaque_dir(struct work_struct *work)
11012+{
11013+ struct sioq_args *args = container_of(work, struct sioq_args, work);
11014+
11015+ args->ret = lookup_one_len(UNIONFS_DIR_OPAQUE, args->is_opaque.dentry,
11016+ sizeof(UNIONFS_DIR_OPAQUE) - 1);
11017+ complete(&args->comp);
11018+}
11019+
11020+int make_dir_opaque(struct dentry *dentry, int bindex)
11021+{
11022+ int err = 0;
11023+ struct dentry *lower_dentry, *diropq;
11024+ struct inode *lower_dir;
11025+ struct nameidata nd;
11026+ kernel_cap_t orig_cap;
11027+
11028+ /*
11029+ * Opaque directory whiteout markers are special files (like regular
11030+ * whiteouts), and should appear to the users as if they don't
11031+ * exist. They should be created/deleted regardless of directory
11032+ * search/create permissions, but only for the duration of this
11033+ * creation of the .wh.__dir_opaque: file. Note, this does not
11034+ * circumvent normal ->permission).
11035+ */
11036+ orig_cap = current->cap_effective;
11037+ cap_raise(current->cap_effective, CAP_DAC_READ_SEARCH);
11038+ cap_raise(current->cap_effective, CAP_DAC_OVERRIDE);
11039+
11040+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
11041+ lower_dir = lower_dentry->d_inode;
11042+ BUG_ON(!S_ISDIR(dentry->d_inode->i_mode) ||
11043+ !S_ISDIR(lower_dir->i_mode));
11044+
11045+ mutex_lock(&lower_dir->i_mutex);
11046+ diropq = lookup_one_len(UNIONFS_DIR_OPAQUE, lower_dentry,
11047+ sizeof(UNIONFS_DIR_OPAQUE) - 1);
11048+ if (IS_ERR(diropq)) {
11049+ err = PTR_ERR(diropq);
11050+ goto out;
11051+ }
11052+
11053+ err = init_lower_nd(&nd, LOOKUP_CREATE);
11054+ if (unlikely(err < 0))
11055+ goto out;
11056+ if (!diropq->d_inode)
11057+ err = vfs_create(lower_dir, diropq, S_IRUGO, &nd);
11058+ if (!err)
11059+ dbopaque(dentry) = bindex;
11060+ release_lower_nd(&nd, err);
11061+
11062+ dput(diropq);
11063+
11064+out:
11065+ mutex_unlock(&lower_dir->i_mutex);
11066+ current->cap_effective = orig_cap;
11067+ return err;
11068+}
11069diff --git a/fs/unionfs/xattr.c b/fs/unionfs/xattr.c
11070new file mode 100644
11071index 0000000..93a8fce
11072--- /dev/null
11073+++ b/fs/unionfs/xattr.c
11074@@ -0,0 +1,153 @@
11075+/*
11076+ * Copyright (c) 2003-2008 Erez Zadok
11077+ * Copyright (c) 2003-2006 Charles P. Wright
11078+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
11079+ * Copyright (c) 2005-2006 Junjiro Okajima
11080+ * Copyright (c) 2005 Arun M. Krishnakumar
11081+ * Copyright (c) 2004-2006 David P. Quigley
11082+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
11083+ * Copyright (c) 2003 Puja Gupta
11084+ * Copyright (c) 2003 Harikesavan Krishnan
11085+ * Copyright (c) 2003-2008 Stony Brook University
11086+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
11087+ *
11088+ * This program is free software; you can redistribute it and/or modify
11089+ * it under the terms of the GNU General Public License version 2 as
11090+ * published by the Free Software Foundation.
11091+ */
11092+
11093+#include "union.h"
11094+
11095+/* This is lifted from fs/xattr.c */
11096+void *unionfs_xattr_alloc(size_t size, size_t limit)
11097+{
11098+ void *ptr;
11099+
11100+ if (size > limit)
11101+ return ERR_PTR(-E2BIG);
11102+
11103+ if (!size) /* size request, no buffer is needed */
11104+ return NULL;
11105+
11106+ ptr = kmalloc(size, GFP_KERNEL);
11107+ if (unlikely(!ptr))
11108+ return ERR_PTR(-ENOMEM);
11109+ return ptr;
11110+}
11111+
11112+/*
11113+ * BKL held by caller.
11114+ * dentry->d_inode->i_mutex locked
11115+ */
11116+ssize_t unionfs_getxattr(struct dentry *dentry, const char *name, void *value,
11117+ size_t size)
11118+{
11119+ struct dentry *lower_dentry = NULL;
11120+ int err = -EOPNOTSUPP;
11121+
11122+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
11123+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
11124+
11125+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
11126+ err = -ESTALE;
11127+ goto out;
11128+ }
11129+
11130+ lower_dentry = unionfs_lower_dentry(dentry);
11131+
11132+ err = vfs_getxattr(lower_dentry, (char *) name, value, size);
11133+
11134+out:
11135+ unionfs_check_dentry(dentry);
11136+ unionfs_unlock_dentry(dentry);
11137+ unionfs_read_unlock(dentry->d_sb);
11138+ return err;
11139+}
11140+
11141+/*
11142+ * BKL held by caller.
11143+ * dentry->d_inode->i_mutex locked
11144+ */
11145+int unionfs_setxattr(struct dentry *dentry, const char *name,
11146+ const void *value, size_t size, int flags)
11147+{
11148+ struct dentry *lower_dentry = NULL;
11149+ int err = -EOPNOTSUPP;
11150+
11151+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
11152+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
11153+
11154+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
11155+ err = -ESTALE;
11156+ goto out;
11157+ }
11158+
11159+ lower_dentry = unionfs_lower_dentry(dentry);
11160+
11161+ err = vfs_setxattr(lower_dentry, (char *) name, (void *) value,
11162+ size, flags);
11163+
11164+out:
11165+ unionfs_check_dentry(dentry);
11166+ unionfs_unlock_dentry(dentry);
11167+ unionfs_read_unlock(dentry->d_sb);
11168+ return err;
11169+}
11170+
11171+/*
11172+ * BKL held by caller.
11173+ * dentry->d_inode->i_mutex locked
11174+ */
11175+int unionfs_removexattr(struct dentry *dentry, const char *name)
11176+{
11177+ struct dentry *lower_dentry = NULL;
11178+ int err = -EOPNOTSUPP;
11179+
11180+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
11181+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
11182+
11183+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
11184+ err = -ESTALE;
11185+ goto out;
11186+ }
11187+
11188+ lower_dentry = unionfs_lower_dentry(dentry);
11189+
11190+ err = vfs_removexattr(lower_dentry, (char *) name);
11191+
11192+out:
11193+ unionfs_check_dentry(dentry);
11194+ unionfs_unlock_dentry(dentry);
11195+ unionfs_read_unlock(dentry->d_sb);
11196+ return err;
11197+}
11198+
11199+/*
11200+ * BKL held by caller.
11201+ * dentry->d_inode->i_mutex locked
11202+ */
11203+ssize_t unionfs_listxattr(struct dentry *dentry, char *list, size_t size)
11204+{
11205+ struct dentry *lower_dentry = NULL;
11206+ int err = -EOPNOTSUPP;
11207+ char *encoded_list = NULL;
11208+
11209+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
11210+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
11211+
11212+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
11213+ err = -ESTALE;
11214+ goto out;
11215+ }
11216+
11217+ lower_dentry = unionfs_lower_dentry(dentry);
11218+
11219+ encoded_list = list;
11220+ err = vfs_listxattr(lower_dentry, encoded_list, size);
11221+
11222+out:
11223+ unionfs_check_dentry(dentry);
11224+ unionfs_unlock_dentry(dentry);
11225+ unionfs_read_unlock(dentry->d_sb);
11226+ return err;
11227+}
11228diff --git a/include/linux/fs_stack.h b/include/linux/fs_stack.h
11229index bb516ce..6615a52 100644
11230--- a/include/linux/fs_stack.h
11231+++ b/include/linux/fs_stack.h
11232@@ -1,17 +1,27 @@
11233+/*
11234+ * Copyright (c) 2006-2007 Erez Zadok
11235+ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
11236+ * Copyright (c) 2006-2007 Stony Brook University
11237+ * Copyright (c) 2006-2007 The Research Foundation of SUNY
11238+ *
11239+ * This program is free software; you can redistribute it and/or modify
11240+ * it under the terms of the GNU General Public License version 2 as
11241+ * published by the Free Software Foundation.
11242+ */
11243+
11244 #ifndef _LINUX_FS_STACK_H
11245 #define _LINUX_FS_STACK_H
11246
11247-/* This file defines generic functions used primarily by stackable
11248+/*
11249+ * This file defines generic functions used primarily by stackable
11250 * filesystems; none of these functions require i_mutex to be held.
11251 */
11252
11253 #include <linux/fs.h>
11254
11255 /* externs for fs/stack.c */
11256-extern void fsstack_copy_attr_all(struct inode *dest, const struct inode *src,
11257- int (*get_nlinks)(struct inode *));
11258-
11259-extern void fsstack_copy_inode_size(struct inode *dst, const struct inode *src);
11260+extern void fsstack_copy_attr_all(struct inode *dest, const struct inode *src);
11261+extern void fsstack_copy_inode_size(struct inode *dst, struct inode *src);
11262
11263 /* inlines */
11264 static inline void fsstack_copy_attr_atime(struct inode *dest,
11265diff --git a/include/linux/magic.h b/include/linux/magic.h
11266index 1fa0c2c..67043ed 100644
11267--- a/include/linux/magic.h
11268+++ b/include/linux/magic.h
11269@@ -35,6 +35,8 @@
11270 #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
11271 #define REISER2FS_JR_SUPER_MAGIC_STRING "ReIsEr3Fs"
11272
11273+#define UNIONFS_SUPER_MAGIC 0xf15f083d
11274+
11275 #define SMB_SUPER_MAGIC 0x517B
11276 #define USBDEVICE_SUPER_MAGIC 0x9fa2
11277 #define CGROUP_SUPER_MAGIC 0x27e0eb
11278diff --git a/include/linux/splice.h b/include/linux/splice.h
11279index 528dcb9..4b5727c 100644
11280--- a/include/linux/splice.h
11281+++ b/include/linux/splice.h
11282@@ -70,5 +70,10 @@ extern ssize_t splice_to_pipe(struct pipe_inode_info *,
11283 struct splice_pipe_desc *);
11284 extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
11285 splice_direct_actor *);
11286+extern long vfs_splice_from(struct pipe_inode_info *pipe, struct file *out,
11287+ loff_t *ppos, size_t len, unsigned int flags);
11288+extern long vfs_splice_to(struct file *in, loff_t *ppos,
11289+ struct pipe_inode_info *pipe, size_t len,
11290+ unsigned int flags);
11291
11292 #endif
11293diff --git a/include/linux/union_fs.h b/include/linux/union_fs.h
11294new file mode 100644
11295index 0000000..bc15a16
11296--- /dev/null
11297+++ b/include/linux/union_fs.h
11298@@ -0,0 +1,22 @@
11299+/*
11300+ * Copyright (c) 2003-2008 Erez Zadok
11301+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
11302+ * Copyright (c) 2003-2008 Stony Brook University
11303+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
11304+ *
11305+ * This program is free software; you can redistribute it and/or modify
11306+ * it under the terms of the GNU General Public License version 2 as
11307+ * published by the Free Software Foundation.
11308+ */
11309+
11310+#ifndef _LINUX_UNION_FS_H
11311+#define _LINUX_UNION_FS_H
11312+
11313+/*
11314+ * DEFINITIONS FOR USER AND KERNEL CODE:
11315+ */
11316+# define UNIONFS_IOCTL_INCGEN _IOR(0x15, 11, int)
11317+# define UNIONFS_IOCTL_QUERYFILE _IOR(0x15, 15, int)
11318+
11319+#endif /* _LINUX_UNIONFS_H */
11320+
diff --git a/meta/packages/linux/linux-moblin2-2.6.27-rc1/0011_workaround_unidef_step.patch b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0011_workaround_unidef_step.patch
new file mode 100644
index 0000000000..a77ff3c62f
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0011_workaround_unidef_step.patch
@@ -0,0 +1,10 @@
1--- linux.trees.git/include/linux/videodev2.h.org 2008-08-15 16:31:03.000000000 -0700
2+++ linux.trees.git/include/linux/videodev2.h 2008-08-15 16:31:11.000000000 -0700
3@@ -59,7 +59,6 @@
4 #include <linux/time.h> /* need struct timeval */
5 #include <linux/compiler.h> /* need __user */
6 #else
7-#define __user
8 #include <sys/time.h>
9 #endif
10 #include <linux/ioctl.h>
diff --git a/meta/packages/linux/linux-moblin2-2.6.27-rc1/0012_intelfb_945gme.patch b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0012_intelfb_945gme.patch
new file mode 100644
index 0000000000..15ebe56328
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0012_intelfb_945gme.patch
@@ -0,0 +1,153 @@
1The following patch adds support for Intel's 945GME graphics chip to
2the intelfb driver. I have assumed that the 945GME is identical to the
3already-supported 945GM apart from its PCI IDs; this is based on a quick
4look at the X driver for these chips which seems to treat them
5identically.
6
7Signed-off-by: Phil Endecott <spam_from_intelfb@chezphil.org>
8
9---
10
11The 945GME is used in the ASUS Eee 901, and I coded this in the hope that
12I'd be able to use it to get a console at the native 1024x600 resolution
13which is not known to the BIOS. I realised too late that the intelfb
14driver does not support mode changing on laptops, so it won't be any
15use for me. But rather than throw it away I will post it here as
16essentially "untested"; maybe someone who knows more about this driver,
17and with more useful hardware to test on, can pick it up.
18
19diff --git a/Documentation/fb/intelfb.txt b/Documentation/fb/intelfb.txt
20index 27a3160..dd9e944 100644
21--- a/Documentation/fb/intelfb.txt
22+++ b/Documentation/fb/intelfb.txt
23@@ -14,6 +14,7 @@ graphics devices. These would include:
24 Intel 915GM
25 Intel 945G
26 Intel 945GM
27+ Intel 945GME
28 Intel 965G
29 Intel 965GM
30
31diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
32index 3325fbd..a50bea6 100644
33--- a/drivers/video/intelfb/intelfb.h
34+++ b/drivers/video/intelfb/intelfb.h
35@@ -12,9 +12,9 @@
36 #endif
37
38 /*** Version/name ***/
39-#define INTELFB_VERSION "0.9.5"
40+#define INTELFB_VERSION "0.9.6"
41 #define INTELFB_MODULE_NAME "intelfb"
42-#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM"
43+#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/945GME/965G/965GM"
44
45
46 /*** Debug/feature defines ***/
47@@ -58,6 +58,7 @@
48 #define PCI_DEVICE_ID_INTEL_915GM 0x2592
49 #define PCI_DEVICE_ID_INTEL_945G 0x2772
50 #define PCI_DEVICE_ID_INTEL_945GM 0x27A2
51+#define PCI_DEVICE_ID_INTEL_945GME 0x27AE
52 #define PCI_DEVICE_ID_INTEL_965G 0x29A2
53 #define PCI_DEVICE_ID_INTEL_965GM 0x2A02
54
55@@ -160,6 +161,7 @@ enum intel_chips {
56 INTEL_915GM,
57 INTEL_945G,
58 INTEL_945GM,
59+ INTEL_945GME,
60 INTEL_965G,
61 INTEL_965GM,
62 };
63@@ -363,6 +365,7 @@ struct intelfb_info {
64 ((dinfo)->chipset == INTEL_915GM) || \
65 ((dinfo)->chipset == INTEL_945G) || \
66 ((dinfo)->chipset == INTEL_945GM) || \
67+ ((dinfo)->chipset == INTEL_945GME) || \
68 ((dinfo)->chipset == INTEL_965G) || \
69 ((dinfo)->chipset == INTEL_965GM))
70
71diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
72index fcf9fad..5d896b8 100644
73--- a/drivers/video/intelfb/intelfb_i2c.c
74+++ b/drivers/video/intelfb/intelfb_i2c.c
75@@ -171,6 +171,7 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
76 /* has some LVDS + tv-out */
77 case INTEL_945G:
78 case INTEL_945GM:
79+ case INTEL_945GME:
80 case INTEL_965G:
81 case INTEL_965GM:
82 /* SDVO ports have a single control bus - 2 devices */
83diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
84index e44303f..a09e236 100644
85--- a/drivers/video/intelfb/intelfbdrv.c
86+++ b/drivers/video/intelfb/intelfbdrv.c
87@@ -2,7 +2,7 @@
88 * intelfb
89 *
90 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/
91- * 945G/945GM/965G/965GM integrated graphics chips.
92+ * 945G/945GM/945GME/965G/965GM integrated graphics chips.
93 *
94 * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
95 * 2004 Sylvain Meyer
96@@ -102,6 +102,9 @@
97 *
98 * 04/2008 - Version 0.9.5
99 * Add support for 965G/965GM. (Maik Broemme <mbroemme@plusserver.de>)
100+ *
101+ * 08/2008 - Version 0.9.6
102+ * Add support for 945GME. (Phil Endecott <spam_from_intelfb@chezphil.org>)
103 */
104
105 #include <linux/module.h>
106@@ -183,6 +186,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = {
107 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
108 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G },
109 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM },
110+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GME, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GME },
111 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965G },
112 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965GM },
113 { 0, }
114@@ -555,6 +559,7 @@ static int __devinit intelfb_pci_register(struct pci_dev *pdev,
115 (ent->device == PCI_DEVICE_ID_INTEL_915GM) ||
116 (ent->device == PCI_DEVICE_ID_INTEL_945G) ||
117 (ent->device == PCI_DEVICE_ID_INTEL_945GM) ||
118+ (ent->device == PCI_DEVICE_ID_INTEL_945GME) ||
119 (ent->device == PCI_DEVICE_ID_INTEL_965G) ||
120 (ent->device == PCI_DEVICE_ID_INTEL_965GM)) {
121
122diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
123index 8e6d6a4..8b26b27 100644
124--- a/drivers/video/intelfb/intelfbhw.c
125+++ b/drivers/video/intelfb/intelfbhw.c
126@@ -143,6 +143,12 @@ int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
127 dinfo->mobile = 1;
128 dinfo->pll_index = PLLS_I9xx;
129 return 0;
130+ case PCI_DEVICE_ID_INTEL_945GME:
131+ dinfo->name = "Intel(R) 945GME";
132+ dinfo->chipset = INTEL_945GME;
133+ dinfo->mobile = 1;
134+ dinfo->pll_index = PLLS_I9xx;
135+ return 0;
136 case PCI_DEVICE_ID_INTEL_965G:
137 dinfo->name = "Intel(R) 965G";
138 dinfo->chipset = INTEL_965G;
139@@ -186,6 +192,7 @@ int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
140 case PCI_DEVICE_ID_INTEL_915GM:
141 case PCI_DEVICE_ID_INTEL_945G:
142 case PCI_DEVICE_ID_INTEL_945GM:
143+ case PCI_DEVICE_ID_INTEL_945GME:
144 case PCI_DEVICE_ID_INTEL_965G:
145 case PCI_DEVICE_ID_INTEL_965GM:
146 /* 915, 945 and 965 chipsets support a 256MB aperture.
147
148
149--
150To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
151the body of a message to majordomo@vger.kernel.org
152More majordomo info at http://vger.kernel.org/majordomo-info.html
153Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file
diff --git a/meta/packages/linux/linux-moblin2-2.6.27-rc1/defconfig-eee901 b/meta/packages/linux/linux-moblin2-2.6.27-rc1/defconfig-eee901
new file mode 100644
index 0000000000..489bfce8ff
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2-2.6.27-rc1/defconfig-eee901
@@ -0,0 +1,2322 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.27-rc1
4# Wed Sep 10 12:10:52 2008
5#
6# CONFIG_64BIT is not set
7CONFIG_X86_32=y
8# CONFIG_X86_64 is not set
9CONFIG_X86=y
10CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
11# CONFIG_GENERIC_LOCKBREAK is not set
12CONFIG_GENERIC_TIME=y
13CONFIG_GENERIC_CMOS_UPDATE=y
14CONFIG_CLOCKSOURCE_WATCHDOG=y
15CONFIG_GENERIC_CLOCKEVENTS=y
16CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
17CONFIG_LOCKDEP_SUPPORT=y
18CONFIG_STACKTRACE_SUPPORT=y
19CONFIG_HAVE_LATENCYTOP_SUPPORT=y
20CONFIG_FAST_CMPXCHG_LOCAL=y
21CONFIG_MMU=y
22CONFIG_ZONE_DMA=y
23CONFIG_GENERIC_ISA_DMA=y
24CONFIG_GENERIC_IOMAP=y
25CONFIG_GENERIC_BUG=y
26CONFIG_GENERIC_HWEIGHT=y
27# CONFIG_GENERIC_GPIO is not set
28CONFIG_ARCH_MAY_HAVE_PC_FDC=y
29# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
30CONFIG_RWSEM_XCHGADD_ALGORITHM=y
31# CONFIG_ARCH_HAS_ILOG2_U32 is not set
32# CONFIG_ARCH_HAS_ILOG2_U64 is not set
33CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
34CONFIG_GENERIC_CALIBRATE_DELAY=y
35# CONFIG_GENERIC_TIME_VSYSCALL is not set
36CONFIG_ARCH_HAS_CPU_RELAX=y
37CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
38CONFIG_HAVE_SETUP_PER_CPU_AREA=y
39# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
40CONFIG_ARCH_HIBERNATION_POSSIBLE=y
41CONFIG_ARCH_SUSPEND_POSSIBLE=y
42# CONFIG_ZONE_DMA32 is not set
43CONFIG_ARCH_POPULATES_NODE_MAP=y
44# CONFIG_AUDIT_ARCH is not set
45CONFIG_ARCH_SUPPORTS_AOUT=y
46CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
47CONFIG_GENERIC_HARDIRQS=y
48CONFIG_GENERIC_IRQ_PROBE=y
49CONFIG_GENERIC_PENDING_IRQ=y
50CONFIG_X86_SMP=y
51CONFIG_X86_32_SMP=y
52CONFIG_X86_HT=y
53CONFIG_X86_BIOS_REBOOT=y
54CONFIG_X86_TRAMPOLINE=y
55CONFIG_KTIME_SCALAR=y
56CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
57
58#
59# General setup
60#
61CONFIG_EXPERIMENTAL=y
62CONFIG_LOCK_KERNEL=y
63CONFIG_INIT_ENV_ARG_LIMIT=32
64CONFIG_LOCALVERSION="-eee901"
65# CONFIG_LOCALVERSION_AUTO is not set
66CONFIG_SWAP=y
67CONFIG_SYSVIPC=y
68CONFIG_SYSVIPC_SYSCTL=y
69CONFIG_POSIX_MQUEUE=y
70CONFIG_BSD_PROCESS_ACCT=y
71CONFIG_BSD_PROCESS_ACCT_V3=y
72CONFIG_TASKSTATS=y
73CONFIG_TASK_DELAY_ACCT=y
74CONFIG_TASK_XACCT=y
75CONFIG_TASK_IO_ACCOUNTING=y
76CONFIG_AUDIT=y
77CONFIG_AUDITSYSCALL=y
78CONFIG_AUDIT_TREE=y
79# CONFIG_IKCONFIG is not set
80CONFIG_LOG_BUF_SHIFT=17
81# CONFIG_CGROUPS is not set
82CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
83# CONFIG_GROUP_SCHED is not set
84# CONFIG_SYSFS_DEPRECATED_V2 is not set
85CONFIG_RELAY=y
86CONFIG_NAMESPACES=y
87# CONFIG_UTS_NS is not set
88# CONFIG_IPC_NS is not set
89CONFIG_USER_NS=y
90# CONFIG_PID_NS is not set
91CONFIG_BLK_DEV_INITRD=y
92CONFIG_INITRAMFS_SOURCE=""
93CONFIG_CC_OPTIMIZE_FOR_SIZE=y
94CONFIG_SYSCTL=y
95# CONFIG_EMBEDDED is not set
96CONFIG_UID16=y
97CONFIG_SYSCTL_SYSCALL=y
98CONFIG_SYSCTL_SYSCALL_CHECK=y
99CONFIG_KALLSYMS=y
100CONFIG_KALLSYMS_ALL=y
101CONFIG_KALLSYMS_EXTRA_PASS=y
102CONFIG_HOTPLUG=y
103CONFIG_PRINTK=y
104CONFIG_BUG=y
105CONFIG_ELF_CORE=y
106CONFIG_PCSPKR_PLATFORM=y
107# CONFIG_COMPAT_BRK is not set
108CONFIG_BASE_FULL=y
109CONFIG_FUTEX=y
110CONFIG_ANON_INODES=y
111CONFIG_EPOLL=y
112CONFIG_SIGNALFD=y
113CONFIG_TIMERFD=y
114CONFIG_EVENTFD=y
115CONFIG_SHMEM=y
116CONFIG_VM_EVENT_COUNTERS=y
117CONFIG_SLAB=y
118# CONFIG_SLUB is not set
119# CONFIG_SLOB is not set
120CONFIG_PROFILING=y
121# CONFIG_MARKERS is not set
122# CONFIG_OPROFILE is not set
123CONFIG_HAVE_OPROFILE=y
124# CONFIG_KPROBES is not set
125CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
126CONFIG_HAVE_IOREMAP_PROT=y
127CONFIG_HAVE_KPROBES=y
128CONFIG_HAVE_KRETPROBES=y
129# CONFIG_HAVE_ARCH_TRACEHOOK is not set
130# CONFIG_HAVE_DMA_ATTRS is not set
131CONFIG_USE_GENERIC_SMP_HELPERS=y
132# CONFIG_HAVE_CLK is not set
133CONFIG_PROC_PAGE_MONITOR=y
134CONFIG_HAVE_GENERIC_DMA_COHERENT=y
135CONFIG_SLABINFO=y
136CONFIG_RT_MUTEXES=y
137# CONFIG_TINY_SHMEM is not set
138CONFIG_BASE_SMALL=0
139CONFIG_MODULES=y
140# CONFIG_MODULE_FORCE_LOAD is not set
141CONFIG_MODULE_UNLOAD=y
142# CONFIG_MODULE_FORCE_UNLOAD is not set
143# CONFIG_MODVERSIONS is not set
144# CONFIG_MODULE_SRCVERSION_ALL is not set
145CONFIG_KMOD=y
146CONFIG_STOP_MACHINE=y
147CONFIG_BLOCK=y
148# CONFIG_LBD is not set
149CONFIG_BLK_DEV_IO_TRACE=y
150# CONFIG_LSF is not set
151CONFIG_BLK_DEV_BSG=y
152# CONFIG_BLK_DEV_INTEGRITY is not set
153
154#
155# IO Schedulers
156#
157CONFIG_IOSCHED_NOOP=y
158# CONFIG_IOSCHED_AS is not set
159# CONFIG_IOSCHED_DEADLINE is not set
160CONFIG_IOSCHED_CFQ=y
161# CONFIG_DEFAULT_AS is not set
162# CONFIG_DEFAULT_DEADLINE is not set
163CONFIG_DEFAULT_CFQ=y
164# CONFIG_DEFAULT_NOOP is not set
165CONFIG_DEFAULT_IOSCHED="cfq"
166CONFIG_CLASSIC_RCU=y
167
168#
169# Processor type and features
170#
171CONFIG_TICK_ONESHOT=y
172CONFIG_NO_HZ=y
173CONFIG_HIGH_RES_TIMERS=y
174CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
175CONFIG_SMP=y
176CONFIG_X86_FIND_SMP_CONFIG=y
177CONFIG_X86_MPPARSE=y
178CONFIG_X86_PC=y
179# CONFIG_X86_ELAN is not set
180# CONFIG_X86_VOYAGER is not set
181# CONFIG_X86_GENERICARCH is not set
182# CONFIG_X86_VSMP is not set
183# CONFIG_X86_RDC321X is not set
184CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
185# CONFIG_PARAVIRT_GUEST is not set
186# CONFIG_MEMTEST is not set
187# CONFIG_M386 is not set
188# CONFIG_M486 is not set
189# CONFIG_M586 is not set
190# CONFIG_M586TSC is not set
191# CONFIG_M586MMX is not set
192CONFIG_M686=y
193# CONFIG_MPENTIUMII is not set
194# CONFIG_MPENTIUMIII is not set
195# CONFIG_MPENTIUMM is not set
196# CONFIG_MPENTIUM4 is not set
197# CONFIG_MK6 is not set
198# CONFIG_MK7 is not set
199# CONFIG_MK8 is not set
200# CONFIG_MCRUSOE is not set
201# CONFIG_MEFFICEON is not set
202# CONFIG_MWINCHIPC6 is not set
203# CONFIG_MWINCHIP2 is not set
204# CONFIG_MWINCHIP3D is not set
205# CONFIG_MGEODEGX1 is not set
206# CONFIG_MGEODE_LX is not set
207# CONFIG_MCYRIXIII is not set
208# CONFIG_MVIAC3_2 is not set
209# CONFIG_MVIAC7 is not set
210# CONFIG_MPSC is not set
211# CONFIG_MCORE2 is not set
212# CONFIG_GENERIC_CPU is not set
213# CONFIG_X86_GENERIC is not set
214CONFIG_X86_CPU=y
215CONFIG_X86_CMPXCHG=y
216CONFIG_X86_L1_CACHE_SHIFT=5
217CONFIG_X86_XADD=y
218# CONFIG_X86_PPRO_FENCE is not set
219CONFIG_X86_WP_WORKS_OK=y
220CONFIG_X86_INVLPG=y
221CONFIG_X86_BSWAP=y
222CONFIG_X86_POPAD_OK=y
223CONFIG_X86_USE_PPRO_CHECKSUM=y
224CONFIG_X86_P6_NOP=y
225CONFIG_X86_TSC=y
226CONFIG_X86_CMOV=y
227CONFIG_X86_MINIMUM_CPU_FAMILY=6
228CONFIG_X86_DEBUGCTLMSR=y
229CONFIG_HPET_TIMER=y
230CONFIG_HPET_EMULATE_RTC=y
231CONFIG_DMI=y
232# CONFIG_IOMMU_HELPER is not set
233CONFIG_NR_CPUS=2
234CONFIG_SCHED_SMT=y
235CONFIG_SCHED_MC=y
236# CONFIG_PREEMPT_NONE is not set
237CONFIG_PREEMPT_VOLUNTARY=y
238# CONFIG_PREEMPT is not set
239CONFIG_X86_LOCAL_APIC=y
240CONFIG_X86_IO_APIC=y
241CONFIG_X86_MCE=y
242# CONFIG_X86_MCE_NONFATAL is not set
243# CONFIG_X86_MCE_P4THERMAL is not set
244CONFIG_VM86=y
245# CONFIG_TOSHIBA is not set
246# CONFIG_I8K is not set
247# CONFIG_X86_REBOOTFIXUPS is not set
248CONFIG_MICROCODE=y
249CONFIG_MICROCODE_OLD_INTERFACE=y
250CONFIG_X86_MSR=y
251CONFIG_X86_CPUID=y
252# CONFIG_NOHIGHMEM is not set
253CONFIG_HIGHMEM4G=y
254# CONFIG_HIGHMEM64G is not set
255CONFIG_PAGE_OFFSET=0xC0000000
256CONFIG_HIGHMEM=y
257CONFIG_NEED_NODE_MEMMAP_SIZE=y
258CONFIG_ARCH_FLATMEM_ENABLE=y
259CONFIG_ARCH_SPARSEMEM_ENABLE=y
260CONFIG_ARCH_SELECT_MEMORY_MODEL=y
261CONFIG_SELECT_MEMORY_MODEL=y
262# CONFIG_FLATMEM_MANUAL is not set
263# CONFIG_DISCONTIGMEM_MANUAL is not set
264CONFIG_SPARSEMEM_MANUAL=y
265CONFIG_SPARSEMEM=y
266CONFIG_HAVE_GET_USER_PAGES_FAST=y
267CONFIG_HAVE_MEMORY_PRESENT=y
268CONFIG_SPARSEMEM_STATIC=y
269# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
270
271#
272# Memory hotplug is currently incompatible with Software Suspend
273#
274CONFIG_PAGEFLAGS_EXTENDED=y
275CONFIG_SPLIT_PTLOCK_CPUS=4
276CONFIG_RESOURCES_64BIT=y
277CONFIG_ZONE_DMA_FLAG=1
278CONFIG_BOUNCE=y
279CONFIG_VIRT_TO_BUS=y
280# CONFIG_HIGHPTE is not set
281# CONFIG_MATH_EMULATION is not set
282CONFIG_MTRR=y
283# CONFIG_MTRR_SANITIZER is not set
284# CONFIG_X86_PAT is not set
285# CONFIG_EFI is not set
286CONFIG_IRQBALANCE=y
287# CONFIG_SECCOMP is not set
288# CONFIG_HZ_100 is not set
289# CONFIG_HZ_250 is not set
290# CONFIG_HZ_300 is not set
291CONFIG_HZ_1000=y
292CONFIG_HZ=1000
293CONFIG_SCHED_HRTICK=y
294CONFIG_KEXEC=y
295CONFIG_CRASH_DUMP=y
296# CONFIG_KEXEC_JUMP is not set
297CONFIG_PHYSICAL_START=0x400000
298CONFIG_RELOCATABLE=y
299CONFIG_PHYSICAL_ALIGN=0x200000
300CONFIG_HOTPLUG_CPU=y
301CONFIG_COMPAT_VDSO=y
302CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
303
304#
305# Power management options
306#
307CONFIG_PM=y
308CONFIG_PM_DEBUG=y
309# CONFIG_PM_VERBOSE is not set
310CONFIG_CAN_PM_TRACE=y
311CONFIG_PM_TRACE=y
312CONFIG_PM_TRACE_RTC=y
313CONFIG_PM_SLEEP_SMP=y
314CONFIG_PM_SLEEP=y
315CONFIG_SUSPEND=y
316# CONFIG_PM_TEST_SUSPEND is not set
317CONFIG_SUSPEND_FREEZER=y
318CONFIG_HIBERNATION=y
319CONFIG_PM_STD_PARTITION=""
320CONFIG_ACPI=y
321CONFIG_ACPI_SLEEP=y
322CONFIG_ACPI_PROCFS=y
323CONFIG_ACPI_PROCFS_POWER=y
324CONFIG_ACPI_SYSFS_POWER=y
325CONFIG_ACPI_PROC_EVENT=y
326CONFIG_ACPI_AC=y
327CONFIG_ACPI_BATTERY=m
328CONFIG_ACPI_BUTTON=y
329CONFIG_ACPI_VIDEO=y
330CONFIG_ACPI_FAN=y
331CONFIG_ACPI_DOCK=y
332# CONFIG_ACPI_BAY is not set
333CONFIG_ACPI_PROCESSOR=y
334CONFIG_ACPI_HOTPLUG_CPU=y
335CONFIG_ACPI_THERMAL=y
336CONFIG_ACPI_WMI=m
337CONFIG_ACPI_ASUS=y
338# CONFIG_ACPI_TOSHIBA is not set
339# CONFIG_ACPI_CUSTOM_DSDT is not set
340CONFIG_ACPI_BLACKLIST_YEAR=0
341# CONFIG_ACPI_DEBUG is not set
342CONFIG_ACPI_EC=y
343# CONFIG_ACPI_PCI_SLOT is not set
344CONFIG_ACPI_POWER=y
345CONFIG_ACPI_SYSTEM=y
346CONFIG_X86_PM_TIMER=y
347CONFIG_ACPI_CONTAINER=y
348CONFIG_ACPI_SBS=m
349# CONFIG_APM is not set
350
351#
352# CPU Frequency scaling
353#
354CONFIG_CPU_FREQ=y
355CONFIG_CPU_FREQ_TABLE=y
356CONFIG_CPU_FREQ_DEBUG=y
357CONFIG_CPU_FREQ_STAT=y
358CONFIG_CPU_FREQ_STAT_DETAILS=y
359CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
360# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
361# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
362# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
363# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
364CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
365# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
366CONFIG_CPU_FREQ_GOV_USERSPACE=y
367CONFIG_CPU_FREQ_GOV_ONDEMAND=y
368# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
369
370#
371# CPUFreq processor drivers
372#
373CONFIG_X86_ACPI_CPUFREQ=y
374# CONFIG_X86_POWERNOW_K6 is not set
375# CONFIG_X86_POWERNOW_K7 is not set
376# CONFIG_X86_POWERNOW_K8 is not set
377# CONFIG_X86_GX_SUSPMOD is not set
378# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
379# CONFIG_X86_SPEEDSTEP_ICH is not set
380# CONFIG_X86_SPEEDSTEP_SMI is not set
381# CONFIG_X86_P4_CLOCKMOD is not set
382# CONFIG_X86_CPUFREQ_NFORCE2 is not set
383# CONFIG_X86_LONGRUN is not set
384# CONFIG_X86_LONGHAUL is not set
385# CONFIG_X86_E_POWERSAVER is not set
386
387#
388# shared options
389#
390# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
391# CONFIG_X86_SPEEDSTEP_LIB is not set
392CONFIG_CPU_IDLE=y
393CONFIG_CPU_IDLE_GOV_LADDER=y
394CONFIG_CPU_IDLE_GOV_MENU=y
395
396#
397# Bus options (PCI etc.)
398#
399CONFIG_PCI=y
400# CONFIG_PCI_GOBIOS is not set
401# CONFIG_PCI_GOMMCONFIG is not set
402# CONFIG_PCI_GODIRECT is not set
403# CONFIG_PCI_GOOLPC is not set
404CONFIG_PCI_GOANY=y
405CONFIG_PCI_BIOS=y
406CONFIG_PCI_DIRECT=y
407CONFIG_PCI_MMCONFIG=y
408CONFIG_PCI_DOMAINS=y
409CONFIG_PCIEPORTBUS=y
410CONFIG_PCIEAER=y
411CONFIG_PCIEASPM=y
412# CONFIG_PCIEASPM_DEBUG is not set
413CONFIG_ARCH_SUPPORTS_MSI=y
414CONFIG_PCI_MSI=y
415CONFIG_PCI_LEGACY=y
416# CONFIG_PCI_DEBUG is not set
417CONFIG_HT_IRQ=y
418CONFIG_ISA_DMA_API=y
419# CONFIG_ISA is not set
420# CONFIG_MCA is not set
421# CONFIG_SCx200 is not set
422# CONFIG_OLPC is not set
423CONFIG_K8_NB=y
424# CONFIG_PCCARD is not set
425# CONFIG_HOTPLUG_PCI is not set
426
427#
428# Executable file formats / Emulations
429#
430CONFIG_BINFMT_ELF=y
431# CONFIG_BINFMT_AOUT is not set
432CONFIG_BINFMT_MISC=y
433
434#
435# Networking
436#
437CONFIG_NET=y
438
439#
440# Networking options
441#
442CONFIG_PACKET=y
443CONFIG_PACKET_MMAP=y
444CONFIG_UNIX=y
445CONFIG_XFRM=y
446CONFIG_XFRM_USER=y
447CONFIG_XFRM_SUB_POLICY=y
448CONFIG_XFRM_MIGRATE=y
449CONFIG_XFRM_STATISTICS=y
450CONFIG_XFRM_IPCOMP=m
451CONFIG_NET_KEY=m
452CONFIG_NET_KEY_MIGRATE=y
453CONFIG_INET=y
454CONFIG_IP_MULTICAST=y
455# CONFIG_IP_ADVANCED_ROUTER is not set
456CONFIG_IP_FIB_HASH=y
457# CONFIG_IP_PNP is not set
458# CONFIG_NET_IPIP is not set
459# CONFIG_NET_IPGRE is not set
460CONFIG_IP_MROUTE=y
461CONFIG_IP_PIMSM_V1=y
462CONFIG_IP_PIMSM_V2=y
463# CONFIG_ARPD is not set
464CONFIG_SYN_COOKIES=y
465CONFIG_INET_AH=m
466CONFIG_INET_ESP=m
467CONFIG_INET_IPCOMP=m
468CONFIG_INET_XFRM_TUNNEL=m
469CONFIG_INET_TUNNEL=m
470CONFIG_INET_XFRM_MODE_TRANSPORT=m
471CONFIG_INET_XFRM_MODE_TUNNEL=m
472CONFIG_INET_XFRM_MODE_BEET=m
473CONFIG_INET_LRO=y
474CONFIG_INET_DIAG=m
475CONFIG_INET_TCP_DIAG=m
476CONFIG_TCP_CONG_ADVANCED=y
477CONFIG_TCP_CONG_BIC=m
478CONFIG_TCP_CONG_CUBIC=y
479# CONFIG_TCP_CONG_WESTWOOD is not set
480# CONFIG_TCP_CONG_HTCP is not set
481# CONFIG_TCP_CONG_HSTCP is not set
482# CONFIG_TCP_CONG_HYBLA is not set
483# CONFIG_TCP_CONG_VEGAS is not set
484# CONFIG_TCP_CONG_SCALABLE is not set
485# CONFIG_TCP_CONG_LP is not set
486# CONFIG_TCP_CONG_VENO is not set
487# CONFIG_TCP_CONG_YEAH is not set
488# CONFIG_TCP_CONG_ILLINOIS is not set
489# CONFIG_DEFAULT_BIC is not set
490CONFIG_DEFAULT_CUBIC=y
491# CONFIG_DEFAULT_HTCP is not set
492# CONFIG_DEFAULT_VEGAS is not set
493# CONFIG_DEFAULT_WESTWOOD is not set
494# CONFIG_DEFAULT_RENO is not set
495CONFIG_DEFAULT_TCP_CONG="cubic"
496CONFIG_TCP_MD5SIG=y
497# CONFIG_IP_VS is not set
498CONFIG_IPV6=y
499CONFIG_IPV6_PRIVACY=y
500CONFIG_IPV6_ROUTER_PREF=y
501CONFIG_IPV6_ROUTE_INFO=y
502CONFIG_IPV6_OPTIMISTIC_DAD=y
503CONFIG_INET6_AH=m
504CONFIG_INET6_ESP=m
505CONFIG_INET6_IPCOMP=m
506CONFIG_IPV6_MIP6=m
507CONFIG_INET6_XFRM_TUNNEL=m
508CONFIG_INET6_TUNNEL=m
509CONFIG_INET6_XFRM_MODE_TRANSPORT=m
510CONFIG_INET6_XFRM_MODE_TUNNEL=m
511CONFIG_INET6_XFRM_MODE_BEET=m
512CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
513CONFIG_IPV6_SIT=m
514CONFIG_IPV6_NDISC_NODETYPE=y
515CONFIG_IPV6_TUNNEL=m
516CONFIG_IPV6_MULTIPLE_TABLES=y
517CONFIG_IPV6_SUBTREES=y
518# CONFIG_IPV6_MROUTE is not set
519CONFIG_NETLABEL=y
520CONFIG_NETWORK_SECMARK=y
521CONFIG_NETFILTER=y
522# CONFIG_NETFILTER_DEBUG is not set
523CONFIG_NETFILTER_ADVANCED=y
524
525#
526# Core Netfilter Configuration
527#
528CONFIG_NETFILTER_NETLINK=m
529CONFIG_NETFILTER_NETLINK_QUEUE=m
530CONFIG_NETFILTER_NETLINK_LOG=m
531CONFIG_NF_CONNTRACK=y
532CONFIG_NF_CT_ACCT=y
533CONFIG_NF_CONNTRACK_MARK=y
534CONFIG_NF_CONNTRACK_SECMARK=y
535CONFIG_NF_CONNTRACK_EVENTS=y
536# CONFIG_NF_CT_PROTO_DCCP is not set
537CONFIG_NF_CT_PROTO_GRE=m
538CONFIG_NF_CT_PROTO_SCTP=m
539CONFIG_NF_CT_PROTO_UDPLITE=m
540CONFIG_NF_CONNTRACK_AMANDA=m
541CONFIG_NF_CONNTRACK_FTP=m
542CONFIG_NF_CONNTRACK_H323=m
543CONFIG_NF_CONNTRACK_IRC=m
544CONFIG_NF_CONNTRACK_NETBIOS_NS=m
545CONFIG_NF_CONNTRACK_PPTP=m
546CONFIG_NF_CONNTRACK_SANE=m
547CONFIG_NF_CONNTRACK_SIP=m
548CONFIG_NF_CONNTRACK_TFTP=m
549CONFIG_NF_CT_NETLINK=m
550CONFIG_NETFILTER_XTABLES=y
551CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
552CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
553CONFIG_NETFILTER_XT_TARGET_DSCP=m
554CONFIG_NETFILTER_XT_TARGET_MARK=m
555CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
556CONFIG_NETFILTER_XT_TARGET_NFLOG=m
557CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
558CONFIG_NETFILTER_XT_TARGET_RATEEST=m
559CONFIG_NETFILTER_XT_TARGET_TRACE=m
560CONFIG_NETFILTER_XT_TARGET_SECMARK=m
561CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
562CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
563CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
564CONFIG_NETFILTER_XT_MATCH_COMMENT=m
565CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
566CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
567CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
568CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
569# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
570CONFIG_NETFILTER_XT_MATCH_DSCP=m
571CONFIG_NETFILTER_XT_MATCH_ESP=m
572CONFIG_NETFILTER_XT_MATCH_HELPER=m
573CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
574CONFIG_NETFILTER_XT_MATCH_LENGTH=m
575CONFIG_NETFILTER_XT_MATCH_LIMIT=m
576CONFIG_NETFILTER_XT_MATCH_MAC=m
577CONFIG_NETFILTER_XT_MATCH_MARK=m
578CONFIG_NETFILTER_XT_MATCH_OWNER=m
579CONFIG_NETFILTER_XT_MATCH_POLICY=m
580CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
581CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
582CONFIG_NETFILTER_XT_MATCH_QUOTA=m
583CONFIG_NETFILTER_XT_MATCH_RATEEST=m
584CONFIG_NETFILTER_XT_MATCH_REALM=m
585CONFIG_NETFILTER_XT_MATCH_SCTP=m
586CONFIG_NETFILTER_XT_MATCH_STATE=y
587CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
588CONFIG_NETFILTER_XT_MATCH_STRING=m
589CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
590CONFIG_NETFILTER_XT_MATCH_TIME=m
591CONFIG_NETFILTER_XT_MATCH_U32=m
592CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
593
594#
595# IP: Netfilter Configuration
596#
597CONFIG_NF_CONNTRACK_IPV4=y
598# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
599CONFIG_IP_NF_QUEUE=m
600CONFIG_IP_NF_IPTABLES=y
601CONFIG_IP_NF_MATCH_RECENT=m
602CONFIG_IP_NF_MATCH_ECN=m
603CONFIG_IP_NF_MATCH_AH=m
604CONFIG_IP_NF_MATCH_TTL=m
605CONFIG_IP_NF_MATCH_ADDRTYPE=m
606CONFIG_IP_NF_FILTER=y
607CONFIG_IP_NF_TARGET_REJECT=y
608CONFIG_IP_NF_TARGET_LOG=m
609CONFIG_IP_NF_TARGET_ULOG=m
610CONFIG_NF_NAT=m
611CONFIG_NF_NAT_NEEDED=y
612CONFIG_IP_NF_TARGET_MASQUERADE=m
613CONFIG_IP_NF_TARGET_REDIRECT=m
614CONFIG_IP_NF_TARGET_NETMAP=m
615CONFIG_NF_NAT_SNMP_BASIC=m
616CONFIG_NF_NAT_PROTO_GRE=m
617CONFIG_NF_NAT_PROTO_UDPLITE=m
618CONFIG_NF_NAT_PROTO_SCTP=m
619CONFIG_NF_NAT_FTP=m
620CONFIG_NF_NAT_IRC=m
621CONFIG_NF_NAT_TFTP=m
622CONFIG_NF_NAT_AMANDA=m
623CONFIG_NF_NAT_PPTP=m
624CONFIG_NF_NAT_H323=m
625CONFIG_NF_NAT_SIP=m
626CONFIG_IP_NF_MANGLE=m
627CONFIG_IP_NF_TARGET_ECN=m
628CONFIG_IP_NF_TARGET_TTL=m
629CONFIG_IP_NF_TARGET_CLUSTERIP=m
630CONFIG_IP_NF_RAW=m
631# CONFIG_IP_NF_SECURITY is not set
632CONFIG_IP_NF_ARPTABLES=m
633CONFIG_IP_NF_ARPFILTER=m
634CONFIG_IP_NF_ARP_MANGLE=m
635
636#
637# IPv6: Netfilter Configuration
638#
639CONFIG_NF_CONNTRACK_IPV6=y
640CONFIG_IP6_NF_QUEUE=m
641CONFIG_IP6_NF_IPTABLES=y
642CONFIG_IP6_NF_MATCH_RT=m
643CONFIG_IP6_NF_MATCH_OPTS=m
644CONFIG_IP6_NF_MATCH_FRAG=m
645CONFIG_IP6_NF_MATCH_HL=m
646CONFIG_IP6_NF_MATCH_IPV6HEADER=m
647CONFIG_IP6_NF_MATCH_AH=m
648CONFIG_IP6_NF_MATCH_MH=m
649CONFIG_IP6_NF_MATCH_EUI64=m
650CONFIG_IP6_NF_FILTER=y
651CONFIG_IP6_NF_TARGET_LOG=m
652CONFIG_IP6_NF_TARGET_REJECT=y
653CONFIG_IP6_NF_MANGLE=m
654CONFIG_IP6_NF_TARGET_HL=m
655CONFIG_IP6_NF_RAW=m
656# CONFIG_IP6_NF_SECURITY is not set
657# CONFIG_IP_DCCP is not set
658# CONFIG_IP_SCTP is not set
659# CONFIG_TIPC is not set
660# CONFIG_ATM is not set
661# CONFIG_BRIDGE is not set
662# CONFIG_VLAN_8021Q is not set
663# CONFIG_DECNET is not set
664# CONFIG_LLC2 is not set
665# CONFIG_IPX is not set
666# CONFIG_ATALK is not set
667# CONFIG_X25 is not set
668# CONFIG_LAPB is not set
669# CONFIG_ECONET is not set
670# CONFIG_WAN_ROUTER is not set
671# CONFIG_NET_SCHED is not set
672CONFIG_NET_CLS_ROUTE=y
673
674#
675# Network testing
676#
677# CONFIG_NET_PKTGEN is not set
678# CONFIG_HAMRADIO is not set
679# CONFIG_CAN is not set
680# CONFIG_IRDA is not set
681CONFIG_BT=m
682CONFIG_BT_L2CAP=m
683CONFIG_BT_SCO=m
684CONFIG_BT_RFCOMM=m
685CONFIG_BT_RFCOMM_TTY=y
686CONFIG_BT_BNEP=m
687# CONFIG_BT_BNEP_MC_FILTER is not set
688# CONFIG_BT_BNEP_PROTO_FILTER is not set
689# CONFIG_BT_HIDP is not set
690
691#
692# Bluetooth device drivers
693#
694CONFIG_BT_HCIUSB=m
695CONFIG_BT_HCIUSB_SCO=y
696CONFIG_BT_HCIBTSDIO=m
697CONFIG_BT_HCIUART=m
698CONFIG_BT_HCIUART_H4=y
699CONFIG_BT_HCIUART_BCSP=y
700CONFIG_BT_HCIUART_LL=y
701CONFIG_BT_HCIBCM203X=m
702CONFIG_BT_HCIBPA10X=m
703CONFIG_BT_HCIBFUSB=m
704CONFIG_BT_HCIVHCI=m
705# CONFIG_AF_RXRPC is not set
706CONFIG_FIB_RULES=y
707
708#
709# Wireless
710#
711CONFIG_CFG80211=m
712CONFIG_NL80211=y
713CONFIG_WIRELESS_EXT=y
714# CONFIG_WIRELESS_EXT_SYSFS is not set
715CONFIG_MAC80211=m
716
717#
718# Rate control algorithm selection
719#
720CONFIG_MAC80211_RC_PID=y
721CONFIG_MAC80211_RC_DEFAULT_PID=y
722CONFIG_MAC80211_RC_DEFAULT="pid"
723CONFIG_MAC80211_MESH=y
724CONFIG_MAC80211_LEDS=y
725CONFIG_MAC80211_DEBUGFS=y
726# CONFIG_MAC80211_DEBUG_MENU is not set
727CONFIG_IEEE80211=m
728# CONFIG_IEEE80211_DEBUG is not set
729CONFIG_IEEE80211_CRYPT_WEP=m
730CONFIG_IEEE80211_CRYPT_CCMP=m
731CONFIG_IEEE80211_CRYPT_TKIP=m
732CONFIG_RFKILL=m
733CONFIG_RFKILL_INPUT=m
734CONFIG_RFKILL_LEDS=y
735# CONFIG_NET_9P is not set
736
737#
738# Device Drivers
739#
740
741#
742# Generic Driver Options
743#
744CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
745CONFIG_STANDALONE=y
746CONFIG_PREVENT_FIRMWARE_BUILD=y
747CONFIG_FW_LOADER=y
748CONFIG_FIRMWARE_IN_KERNEL=y
749CONFIG_EXTRA_FIRMWARE=""
750# CONFIG_DEBUG_DRIVER is not set
751CONFIG_DEBUG_DEVRES=y
752# CONFIG_SYS_HYPERVISOR is not set
753CONFIG_CONNECTOR=y
754CONFIG_PROC_EVENTS=y
755# CONFIG_MTD is not set
756# CONFIG_PARPORT is not set
757CONFIG_PNP=y
758# CONFIG_PNP_DEBUG is not set
759
760#
761# Protocols
762#
763CONFIG_PNPACPI=y
764CONFIG_BLK_DEV=y
765# CONFIG_BLK_DEV_FD is not set
766# CONFIG_BLK_CPQ_DA is not set
767# CONFIG_BLK_CPQ_CISS_DA is not set
768# CONFIG_BLK_DEV_DAC960 is not set
769# CONFIG_BLK_DEV_UMEM is not set
770# CONFIG_BLK_DEV_COW_COMMON is not set
771CONFIG_BLK_DEV_LOOP=y
772CONFIG_BLK_DEV_CRYPTOLOOP=m
773# CONFIG_BLK_DEV_NBD is not set
774# CONFIG_BLK_DEV_SX8 is not set
775# CONFIG_BLK_DEV_UB is not set
776CONFIG_BLK_DEV_RAM=y
777CONFIG_BLK_DEV_RAM_COUNT=16
778CONFIG_BLK_DEV_RAM_SIZE=262144
779# CONFIG_BLK_DEV_XIP is not set
780CONFIG_CDROM_PKTCDVD=m
781CONFIG_CDROM_PKTCDVD_BUFFERS=8
782# CONFIG_CDROM_PKTCDVD_WCACHE is not set
783# CONFIG_ATA_OVER_ETH is not set
784# CONFIG_BLK_DEV_HD is not set
785CONFIG_MISC_DEVICES=y
786# CONFIG_IBM_ASM is not set
787# CONFIG_PHANTOM is not set
788CONFIG_EEPROM_93CX6=m
789# CONFIG_SGI_IOC4 is not set
790CONFIG_TIFM_CORE=m
791CONFIG_TIFM_7XX1=m
792# CONFIG_ACER_WMI is not set
793# CONFIG_FUJITSU_LAPTOP is not set
794# CONFIG_TC1100_WMI is not set
795# CONFIG_HP_WMI is not set
796# CONFIG_MSI_LAPTOP is not set
797# CONFIG_COMPAL_LAPTOP is not set
798# CONFIG_SONY_LAPTOP is not set
799# CONFIG_THINKPAD_ACPI is not set
800# CONFIG_INTEL_MENLOW is not set
801# CONFIG_ENCLOSURE_SERVICES is not set
802# CONFIG_HP_ILO is not set
803CONFIG_HAVE_IDE=y
804# CONFIG_IDE is not set
805
806#
807# SCSI device support
808#
809CONFIG_RAID_ATTRS=m
810CONFIG_SCSI=y
811CONFIG_SCSI_DMA=y
812# CONFIG_SCSI_TGT is not set
813# CONFIG_SCSI_NETLINK is not set
814CONFIG_SCSI_PROC_FS=y
815
816#
817# SCSI support type (disk, tape, CD-ROM)
818#
819CONFIG_BLK_DEV_SD=y
820CONFIG_CHR_DEV_ST=m
821# CONFIG_CHR_DEV_OSST is not set
822CONFIG_BLK_DEV_SR=y
823CONFIG_BLK_DEV_SR_VENDOR=y
824# CONFIG_CHR_DEV_SG is not set
825CONFIG_CHR_DEV_SCH=m
826
827#
828# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
829#
830CONFIG_SCSI_MULTI_LUN=y
831CONFIG_SCSI_CONSTANTS=y
832CONFIG_SCSI_LOGGING=y
833CONFIG_SCSI_SCAN_ASYNC=y
834CONFIG_SCSI_WAIT_SCAN=m
835
836#
837# SCSI Transports
838#
839# CONFIG_SCSI_SPI_ATTRS is not set
840# CONFIG_SCSI_FC_ATTRS is not set
841# CONFIG_SCSI_ISCSI_ATTRS is not set
842# CONFIG_SCSI_SAS_ATTRS is not set
843# CONFIG_SCSI_SAS_LIBSAS is not set
844# CONFIG_SCSI_SRP_ATTRS is not set
845CONFIG_SCSI_LOWLEVEL=y
846# CONFIG_ISCSI_TCP is not set
847# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
848# CONFIG_SCSI_3W_9XXX is not set
849# CONFIG_SCSI_ACARD is not set
850# CONFIG_SCSI_AACRAID is not set
851# CONFIG_SCSI_AIC7XXX is not set
852# CONFIG_SCSI_AIC7XXX_OLD is not set
853# CONFIG_SCSI_AIC79XX is not set
854# CONFIG_SCSI_AIC94XX is not set
855# CONFIG_SCSI_DPT_I2O is not set
856# CONFIG_SCSI_ADVANSYS is not set
857# CONFIG_SCSI_ARCMSR is not set
858# CONFIG_MEGARAID_NEWGEN is not set
859# CONFIG_MEGARAID_LEGACY is not set
860# CONFIG_MEGARAID_SAS is not set
861# CONFIG_SCSI_HPTIOP is not set
862# CONFIG_SCSI_BUSLOGIC is not set
863# CONFIG_SCSI_DMX3191D is not set
864# CONFIG_SCSI_EATA is not set
865# CONFIG_SCSI_FUTURE_DOMAIN is not set
866# CONFIG_SCSI_GDTH is not set
867# CONFIG_SCSI_IPS is not set
868# CONFIG_SCSI_INITIO is not set
869# CONFIG_SCSI_INIA100 is not set
870# CONFIG_SCSI_MVSAS is not set
871# CONFIG_SCSI_STEX is not set
872# CONFIG_SCSI_SYM53C8XX_2 is not set
873# CONFIG_SCSI_IPR is not set
874# CONFIG_SCSI_QLOGIC_1280 is not set
875# CONFIG_SCSI_QLA_FC is not set
876# CONFIG_SCSI_QLA_ISCSI is not set
877# CONFIG_SCSI_LPFC is not set
878# CONFIG_SCSI_DC395x is not set
879# CONFIG_SCSI_DC390T is not set
880# CONFIG_SCSI_NSP32 is not set
881# CONFIG_SCSI_DEBUG is not set
882# CONFIG_SCSI_SRP is not set
883# CONFIG_SCSI_DH is not set
884CONFIG_ATA=y
885# CONFIG_ATA_NONSTANDARD is not set
886CONFIG_ATA_ACPI=y
887# CONFIG_SATA_PMP is not set
888CONFIG_SATA_AHCI=y
889# CONFIG_SATA_SIL24 is not set
890CONFIG_ATA_SFF=y
891# CONFIG_SATA_SVW is not set
892CONFIG_ATA_PIIX=y
893# CONFIG_SATA_MV is not set
894# CONFIG_SATA_NV is not set
895# CONFIG_PDC_ADMA is not set
896# CONFIG_SATA_QSTOR is not set
897# CONFIG_SATA_PROMISE is not set
898# CONFIG_SATA_SX4 is not set
899# CONFIG_SATA_SIL is not set
900# CONFIG_SATA_SIS is not set
901# CONFIG_SATA_ULI is not set
902# CONFIG_SATA_VIA is not set
903# CONFIG_SATA_VITESSE is not set
904# CONFIG_SATA_INIC162X is not set
905# CONFIG_PATA_ACPI is not set
906# CONFIG_PATA_ALI is not set
907# CONFIG_PATA_AMD is not set
908# CONFIG_PATA_ARTOP is not set
909# CONFIG_PATA_ATIIXP is not set
910# CONFIG_PATA_CMD640_PCI is not set
911# CONFIG_PATA_CMD64X is not set
912# CONFIG_PATA_CS5520 is not set
913# CONFIG_PATA_CS5530 is not set
914# CONFIG_PATA_CS5535 is not set
915# CONFIG_PATA_CS5536 is not set
916# CONFIG_PATA_CYPRESS is not set
917# CONFIG_PATA_EFAR is not set
918# CONFIG_ATA_GENERIC is not set
919# CONFIG_PATA_HPT366 is not set
920# CONFIG_PATA_HPT37X is not set
921# CONFIG_PATA_HPT3X2N is not set
922# CONFIG_PATA_HPT3X3 is not set
923# CONFIG_PATA_IT821X is not set
924# CONFIG_PATA_IT8213 is not set
925# CONFIG_PATA_JMICRON is not set
926# CONFIG_PATA_TRIFLEX is not set
927# CONFIG_PATA_MARVELL is not set
928# CONFIG_PATA_MPIIX is not set
929# CONFIG_PATA_OLDPIIX is not set
930# CONFIG_PATA_NETCELL is not set
931# CONFIG_PATA_NINJA32 is not set
932# CONFIG_PATA_NS87410 is not set
933# CONFIG_PATA_NS87415 is not set
934# CONFIG_PATA_OPTI is not set
935# CONFIG_PATA_OPTIDMA is not set
936# CONFIG_PATA_PDC_OLD is not set
937# CONFIG_PATA_RADISYS is not set
938# CONFIG_PATA_RZ1000 is not set
939# CONFIG_PATA_SC1200 is not set
940# CONFIG_PATA_SERVERWORKS is not set
941# CONFIG_PATA_PDC2027X is not set
942# CONFIG_PATA_SIL680 is not set
943# CONFIG_PATA_SIS is not set
944# CONFIG_PATA_VIA is not set
945# CONFIG_PATA_WINBOND is not set
946CONFIG_PATA_SCH=y
947# CONFIG_MD is not set
948# CONFIG_FUSION is not set
949
950#
951# IEEE 1394 (FireWire) support
952#
953
954#
955# Enable only one of the two stacks, unless you know what you are doing
956#
957# CONFIG_FIREWIRE is not set
958# CONFIG_IEEE1394 is not set
959# CONFIG_I2O is not set
960# CONFIG_MACINTOSH_DRIVERS is not set
961CONFIG_NETDEVICES=y
962# CONFIG_DUMMY is not set
963# CONFIG_BONDING is not set
964CONFIG_MACVLAN=m
965# CONFIG_EQUALIZER is not set
966# CONFIG_TUN is not set
967# CONFIG_VETH is not set
968# CONFIG_NET_SB1000 is not set
969# CONFIG_ARCNET is not set
970CONFIG_PHYLIB=m
971
972#
973# MII PHY device drivers
974#
975CONFIG_MARVELL_PHY=m
976CONFIG_DAVICOM_PHY=m
977CONFIG_QSEMI_PHY=m
978CONFIG_LXT_PHY=m
979CONFIG_CICADA_PHY=m
980CONFIG_VITESSE_PHY=m
981CONFIG_SMSC_PHY=m
982CONFIG_BROADCOM_PHY=m
983CONFIG_ICPLUS_PHY=m
984CONFIG_REALTEK_PHY=m
985CONFIG_MDIO_BITBANG=m
986CONFIG_NET_ETHERNET=y
987CONFIG_MII=m
988CONFIG_HAPPYMEAL=m
989CONFIG_SUNGEM=m
990CONFIG_CASSINI=m
991CONFIG_NET_VENDOR_3COM=y
992# CONFIG_VORTEX is not set
993# CONFIG_TYPHOON is not set
994# CONFIG_NET_TULIP is not set
995# CONFIG_HP100 is not set
996# CONFIG_IBM_NEW_EMAC_ZMII is not set
997# CONFIG_IBM_NEW_EMAC_RGMII is not set
998# CONFIG_IBM_NEW_EMAC_TAH is not set
999# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
1000# CONFIG_NET_PCI is not set
1001# CONFIG_B44 is not set
1002CONFIG_NETDEV_1000=y
1003# CONFIG_ACENIC is not set
1004# CONFIG_DL2K is not set
1005# CONFIG_E1000 is not set
1006# CONFIG_E1000E is not set
1007# CONFIG_IP1000 is not set
1008# CONFIG_IGB is not set
1009# CONFIG_NS83820 is not set
1010# CONFIG_HAMACHI is not set
1011# CONFIG_YELLOWFIN is not set
1012# CONFIG_R8169 is not set
1013# CONFIG_SIS190 is not set
1014# CONFIG_SKGE is not set
1015# CONFIG_SKY2 is not set
1016# CONFIG_VIA_VELOCITY is not set
1017# CONFIG_TIGON3 is not set
1018# CONFIG_BNX2 is not set
1019# CONFIG_QLA3XXX is not set
1020CONFIG_ATL1=m
1021CONFIG_ATL1E=m
1022# CONFIG_NETDEV_10000 is not set
1023# CONFIG_TR is not set
1024
1025#
1026# Wireless LAN
1027#
1028CONFIG_WLAN_PRE80211=y
1029# CONFIG_STRIP is not set
1030CONFIG_WLAN_80211=y
1031# CONFIG_IPW2100 is not set
1032# CONFIG_IPW2200 is not set
1033# CONFIG_LIBERTAS is not set
1034# CONFIG_AIRO is not set
1035# CONFIG_HERMES is not set
1036# CONFIG_ATMEL is not set
1037# CONFIG_PRISM54 is not set
1038CONFIG_USB_ZD1201=m
1039CONFIG_USB_NET_RNDIS_WLAN=m
1040CONFIG_RTL8180=m
1041CONFIG_RTL8187=m
1042# CONFIG_ADM8211 is not set
1043# CONFIG_MAC80211_HWSIM is not set
1044# CONFIG_P54_COMMON is not set
1045CONFIG_ATH5K=m
1046# CONFIG_ATH5K_DEBUG is not set
1047CONFIG_IWLWIFI=m
1048CONFIG_IWLCORE=m
1049# CONFIG_IWLWIFI_LEDS is not set
1050CONFIG_IWLWIFI_RFKILL=y
1051CONFIG_IWL4965=m
1052# CONFIG_IWL4965_LEDS is not set
1053# CONFIG_IWL4965_SPECTRUM_MEASUREMENT is not set
1054# CONFIG_IWLWIFI_DEBUG is not set
1055CONFIG_IWL5000=y
1056CONFIG_IWL3945=m
1057CONFIG_IWL3945_RFKILL=y
1058# CONFIG_IWL3945_SPECTRUM_MEASUREMENT is not set
1059# CONFIG_IWL3945_LEDS is not set
1060# CONFIG_IWL3945_DEBUG is not set
1061# CONFIG_HOSTAP is not set
1062# CONFIG_B43 is not set
1063# CONFIG_B43LEGACY is not set
1064# CONFIG_ZD1211RW is not set
1065CONFIG_RT2X00=m
1066CONFIG_RT2X00_LIB=m
1067CONFIG_RT2X00_LIB_PCI=m
1068CONFIG_RT2X00_LIB_USB=m
1069CONFIG_RT2X00_LIB_FIRMWARE=y
1070CONFIG_RT2X00_LIB_RFKILL=y
1071CONFIG_RT2X00_LIB_LEDS=y
1072CONFIG_RT2400PCI=m
1073CONFIG_RT2400PCI_RFKILL=y
1074CONFIG_RT2400PCI_LEDS=y
1075CONFIG_RT2500PCI=m
1076CONFIG_RT2500PCI_RFKILL=y
1077CONFIG_RT2500PCI_LEDS=y
1078CONFIG_RT61PCI=m
1079CONFIG_RT61PCI_RFKILL=y
1080CONFIG_RT61PCI_LEDS=y
1081CONFIG_RT2500USB=m
1082CONFIG_RT2500USB_LEDS=y
1083CONFIG_RT73USB=m
1084CONFIG_RT73USB_LEDS=y
1085CONFIG_RT2X00_LIB_DEBUGFS=y
1086# CONFIG_RT2X00_DEBUG is not set
1087
1088#
1089# USB Network Adapters
1090#
1091CONFIG_USB_CATC=m
1092CONFIG_USB_KAWETH=m
1093CONFIG_USB_PEGASUS=m
1094CONFIG_USB_RTL8150=m
1095CONFIG_USB_USBNET=m
1096CONFIG_USB_NET_AX8817X=m
1097# CONFIG_USB_HSO is not set
1098CONFIG_USB_NET_CDCETHER=m
1099CONFIG_USB_NET_DM9601=m
1100CONFIG_USB_NET_GL620A=m
1101CONFIG_USB_NET_NET1080=m
1102CONFIG_USB_NET_PLUSB=m
1103CONFIG_USB_NET_MCS7830=m
1104CONFIG_USB_NET_RNDIS_HOST=m
1105CONFIG_USB_NET_CDC_SUBSET=m
1106CONFIG_USB_ALI_M5632=y
1107CONFIG_USB_AN2720=y
1108CONFIG_USB_BELKIN=y
1109CONFIG_USB_ARMLINUX=y
1110CONFIG_USB_EPSON2888=y
1111CONFIG_USB_KC2190=y
1112CONFIG_USB_NET_ZAURUS=m
1113# CONFIG_WAN is not set
1114# CONFIG_FDDI is not set
1115# CONFIG_HIPPI is not set
1116CONFIG_PPP=m
1117CONFIG_PPP_MULTILINK=y
1118CONFIG_PPP_FILTER=y
1119CONFIG_PPP_ASYNC=m
1120CONFIG_PPP_SYNC_TTY=m
1121CONFIG_PPP_DEFLATE=m
1122# CONFIG_PPP_BSDCOMP is not set
1123CONFIG_PPP_MPPE=m
1124CONFIG_PPPOE=m
1125CONFIG_PPPOL2TP=m
1126# CONFIG_SLIP is not set
1127CONFIG_SLHC=m
1128CONFIG_NET_FC=y
1129CONFIG_NETCONSOLE=m
1130CONFIG_NETCONSOLE_DYNAMIC=y
1131CONFIG_NETPOLL=y
1132CONFIG_NETPOLL_TRAP=y
1133CONFIG_NET_POLL_CONTROLLER=y
1134# CONFIG_ISDN is not set
1135# CONFIG_PHONE is not set
1136
1137#
1138# Input device support
1139#
1140CONFIG_INPUT=y
1141CONFIG_INPUT_FF_MEMLESS=y
1142CONFIG_INPUT_POLLDEV=m
1143
1144#
1145# Userland interfaces
1146#
1147CONFIG_INPUT_MOUSEDEV=y
1148# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
1149CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
1150CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
1151CONFIG_INPUT_JOYDEV=m
1152CONFIG_INPUT_EVDEV=y
1153# CONFIG_INPUT_EVBUG is not set
1154
1155#
1156# Input Device Drivers
1157#
1158CONFIG_INPUT_KEYBOARD=y
1159CONFIG_KEYBOARD_ATKBD=y
1160# CONFIG_KEYBOARD_SUNKBD is not set
1161# CONFIG_KEYBOARD_LKKBD is not set
1162# CONFIG_KEYBOARD_XTKBD is not set
1163# CONFIG_KEYBOARD_NEWTON is not set
1164# CONFIG_KEYBOARD_STOWAWAY is not set
1165CONFIG_INPUT_MOUSE=y
1166CONFIG_MOUSE_PS2=y
1167CONFIG_MOUSE_PS2_ALPS=y
1168CONFIG_MOUSE_PS2_LOGIPS2PP=y
1169CONFIG_MOUSE_PS2_SYNAPTICS=y
1170CONFIG_MOUSE_PS2_LIFEBOOK=y
1171CONFIG_MOUSE_PS2_TRACKPOINT=y
1172# CONFIG_MOUSE_PS2_TOUCHKIT is not set
1173CONFIG_MOUSE_SERIAL=m
1174# CONFIG_MOUSE_APPLETOUCH is not set
1175CONFIG_MOUSE_VSXXXAA=m
1176CONFIG_INPUT_JOYSTICK=y
1177# CONFIG_JOYSTICK_ANALOG is not set
1178# CONFIG_JOYSTICK_A3D is not set
1179# CONFIG_JOYSTICK_ADI is not set
1180# CONFIG_JOYSTICK_COBRA is not set
1181# CONFIG_JOYSTICK_GF2K is not set
1182# CONFIG_JOYSTICK_GRIP is not set
1183# CONFIG_JOYSTICK_GRIP_MP is not set
1184# CONFIG_JOYSTICK_GUILLEMOT is not set
1185# CONFIG_JOYSTICK_INTERACT is not set
1186# CONFIG_JOYSTICK_SIDEWINDER is not set
1187# CONFIG_JOYSTICK_TMDC is not set
1188# CONFIG_JOYSTICK_IFORCE is not set
1189# CONFIG_JOYSTICK_WARRIOR is not set
1190# CONFIG_JOYSTICK_MAGELLAN is not set
1191# CONFIG_JOYSTICK_SPACEORB is not set
1192# CONFIG_JOYSTICK_SPACEBALL is not set
1193# CONFIG_JOYSTICK_STINGER is not set
1194# CONFIG_JOYSTICK_TWIDJOY is not set
1195# CONFIG_JOYSTICK_ZHENHUA is not set
1196# CONFIG_JOYSTICK_JOYDUMP is not set
1197# CONFIG_JOYSTICK_XPAD is not set
1198# CONFIG_INPUT_TABLET is not set
1199CONFIG_INPUT_TOUCHSCREEN=y
1200CONFIG_TOUCHSCREEN_FUJITSU=m
1201CONFIG_TOUCHSCREEN_GUNZE=m
1202CONFIG_TOUCHSCREEN_ELO=m
1203CONFIG_TOUCHSCREEN_MTOUCH=m
1204CONFIG_TOUCHSCREEN_INEXIO=m
1205CONFIG_TOUCHSCREEN_MK712=m
1206CONFIG_TOUCHSCREEN_PENMOUNT=m
1207CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
1208CONFIG_TOUCHSCREEN_TOUCHWIN=m
1209CONFIG_TOUCHSCREEN_UCB1400=m
1210# CONFIG_TOUCHSCREEN_WM97XX is not set
1211CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
1212CONFIG_TOUCHSCREEN_USB_EGALAX=y
1213CONFIG_TOUCHSCREEN_USB_PANJIT=y
1214CONFIG_TOUCHSCREEN_USB_3M=y
1215CONFIG_TOUCHSCREEN_USB_ITM=y
1216CONFIG_TOUCHSCREEN_USB_ETURBO=y
1217CONFIG_TOUCHSCREEN_USB_GUNZE=y
1218CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
1219CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
1220CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
1221CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
1222CONFIG_TOUCHSCREEN_USB_GOTOP=y
1223CONFIG_TOUCHSCREEN_TOUCHIT213=m
1224CONFIG_INPUT_MISC=y
1225# CONFIG_INPUT_PCSPKR is not set
1226# CONFIG_INPUT_APANEL is not set
1227# CONFIG_INPUT_WISTRON_BTNS is not set
1228CONFIG_INPUT_ATLAS_BTNS=m
1229CONFIG_INPUT_ATI_REMOTE=m
1230CONFIG_INPUT_ATI_REMOTE2=m
1231CONFIG_INPUT_KEYSPAN_REMOTE=m
1232CONFIG_INPUT_POWERMATE=m
1233CONFIG_INPUT_YEALINK=m
1234CONFIG_INPUT_UINPUT=m
1235
1236#
1237# Hardware I/O ports
1238#
1239CONFIG_SERIO=y
1240CONFIG_SERIO_I8042=y
1241CONFIG_SERIO_SERPORT=y
1242# CONFIG_SERIO_CT82C710 is not set
1243# CONFIG_SERIO_PCIPS2 is not set
1244CONFIG_SERIO_LIBPS2=y
1245CONFIG_SERIO_RAW=m
1246# CONFIG_GAMEPORT is not set
1247
1248#
1249# Character devices
1250#
1251CONFIG_VT=y
1252CONFIG_CONSOLE_TRANSLATIONS=y
1253CONFIG_VT_CONSOLE=y
1254CONFIG_HW_CONSOLE=y
1255CONFIG_VT_HW_CONSOLE_BINDING=y
1256# CONFIG_DEVKMEM is not set
1257# CONFIG_SERIAL_NONSTANDARD is not set
1258# CONFIG_NOZOMI is not set
1259
1260#
1261# Serial drivers
1262#
1263# CONFIG_SERIAL_8250 is not set
1264CONFIG_FIX_EARLYCON_MEM=y
1265
1266#
1267# Non-8250 serial port support
1268#
1269# CONFIG_SERIAL_JSM is not set
1270CONFIG_UNIX98_PTYS=y
1271# CONFIG_LEGACY_PTYS is not set
1272# CONFIG_IPMI_HANDLER is not set
1273# CONFIG_HW_RANDOM is not set
1274# CONFIG_NVRAM is not set
1275# CONFIG_R3964 is not set
1276# CONFIG_APPLICOM is not set
1277# CONFIG_SONYPI is not set
1278# CONFIG_MWAVE is not set
1279# CONFIG_PC8736x_GPIO is not set
1280# CONFIG_NSC_GPIO is not set
1281# CONFIG_CS5535_GPIO is not set
1282# CONFIG_RAW_DRIVER is not set
1283CONFIG_HPET=y
1284# CONFIG_HPET_MMAP is not set
1285# CONFIG_HANGCHECK_TIMER is not set
1286# CONFIG_TCG_TPM is not set
1287# CONFIG_TELCLOCK is not set
1288CONFIG_DEVPORT=y
1289CONFIG_I2C=y
1290CONFIG_I2C_BOARDINFO=y
1291# CONFIG_I2C_CHARDEV is not set
1292CONFIG_I2C_ALGOBIT=y
1293
1294#
1295# I2C Hardware Bus support
1296#
1297
1298#
1299# PC SMBus host controller drivers
1300#
1301# CONFIG_I2C_ALI1535 is not set
1302# CONFIG_I2C_ALI1563 is not set
1303# CONFIG_I2C_ALI15X3 is not set
1304# CONFIG_I2C_AMD756 is not set
1305# CONFIG_I2C_AMD8111 is not set
1306# CONFIG_I2C_I801 is not set
1307# CONFIG_I2C_ISCH is not set
1308# CONFIG_I2C_PIIX4 is not set
1309# CONFIG_I2C_NFORCE2 is not set
1310# CONFIG_I2C_SIS5595 is not set
1311# CONFIG_I2C_SIS630 is not set
1312# CONFIG_I2C_SIS96X is not set
1313# CONFIG_I2C_VIA is not set
1314# CONFIG_I2C_VIAPRO is not set
1315
1316#
1317# I2C system bus drivers (mostly embedded / system-on-chip)
1318#
1319# CONFIG_I2C_OCORES is not set
1320# CONFIG_I2C_SIMTEC is not set
1321
1322#
1323# External I2C/SMBus adapter drivers
1324#
1325# CONFIG_I2C_PARPORT_LIGHT is not set
1326# CONFIG_I2C_TAOS_EVM is not set
1327# CONFIG_I2C_TINY_USB is not set
1328
1329#
1330# Graphics adapter I2C/DDC channel drivers
1331#
1332# CONFIG_I2C_VOODOO3 is not set
1333
1334#
1335# Other I2C/SMBus bus drivers
1336#
1337# CONFIG_I2C_PCA_PLATFORM is not set
1338# CONFIG_I2C_STUB is not set
1339# CONFIG_SCx200_ACB is not set
1340
1341#
1342# Miscellaneous I2C Chip support
1343#
1344# CONFIG_DS1682 is not set
1345# CONFIG_AT24 is not set
1346# CONFIG_SENSORS_EEPROM is not set
1347# CONFIG_SENSORS_PCF8574 is not set
1348# CONFIG_PCF8575 is not set
1349# CONFIG_SENSORS_PCA9539 is not set
1350# CONFIG_SENSORS_PCF8591 is not set
1351# CONFIG_SENSORS_MAX6875 is not set
1352# CONFIG_SENSORS_TSL2550 is not set
1353# CONFIG_I2C_DEBUG_CORE is not set
1354# CONFIG_I2C_DEBUG_ALGO is not set
1355# CONFIG_I2C_DEBUG_BUS is not set
1356# CONFIG_I2C_DEBUG_CHIP is not set
1357# CONFIG_SPI is not set
1358CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
1359# CONFIG_GPIOLIB is not set
1360# CONFIG_W1 is not set
1361CONFIG_POWER_SUPPLY=y
1362# CONFIG_POWER_SUPPLY_DEBUG is not set
1363# CONFIG_PDA_POWER is not set
1364# CONFIG_BATTERY_DS2760 is not set
1365# CONFIG_HWMON is not set
1366CONFIG_THERMAL=y
1367# CONFIG_WATCHDOG is not set
1368
1369#
1370# Sonics Silicon Backplane
1371#
1372CONFIG_SSB_POSSIBLE=y
1373# CONFIG_SSB is not set
1374
1375#
1376# Multifunction device drivers
1377#
1378# CONFIG_MFD_CORE is not set
1379# CONFIG_MFD_SM501 is not set
1380# CONFIG_HTC_PASIC3 is not set
1381
1382#
1383# Multimedia devices
1384#
1385
1386#
1387# Multimedia core support
1388#
1389CONFIG_VIDEO_DEV=m
1390CONFIG_VIDEO_V4L2_COMMON=m
1391# CONFIG_VIDEO_ALLOW_V4L1 is not set
1392CONFIG_VIDEO_V4L1_COMPAT=y
1393CONFIG_DVB_CORE=m
1394CONFIG_VIDEO_MEDIA=m
1395
1396#
1397# Multimedia drivers
1398#
1399# CONFIG_MEDIA_ATTACH is not set
1400CONFIG_MEDIA_TUNER=m
1401# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
1402CONFIG_MEDIA_TUNER_SIMPLE=m
1403CONFIG_MEDIA_TUNER_TDA8290=m
1404CONFIG_MEDIA_TUNER_TDA9887=m
1405CONFIG_MEDIA_TUNER_TEA5761=m
1406CONFIG_MEDIA_TUNER_TEA5767=m
1407CONFIG_MEDIA_TUNER_MT20XX=m
1408CONFIG_MEDIA_TUNER_XC2028=m
1409CONFIG_MEDIA_TUNER_XC5000=m
1410CONFIG_VIDEO_V4L2=m
1411# CONFIG_VIDEO_CAPTURE_DRIVERS is not set
1412# CONFIG_RADIO_ADAPTERS is not set
1413# CONFIG_DVB_CAPTURE_DRIVERS is not set
1414# CONFIG_DAB is not set
1415
1416#
1417# Graphics support
1418#
1419CONFIG_AGP=y
1420# CONFIG_AGP_ALI is not set
1421# CONFIG_AGP_ATI is not set
1422# CONFIG_AGP_AMD is not set
1423CONFIG_AGP_AMD64=y
1424CONFIG_AGP_INTEL=y
1425# CONFIG_AGP_NVIDIA is not set
1426# CONFIG_AGP_SIS is not set
1427# CONFIG_AGP_SWORKS is not set
1428# CONFIG_AGP_VIA is not set
1429# CONFIG_AGP_EFFICEON is not set
1430CONFIG_DRM=y
1431# CONFIG_DRM_TDFX is not set
1432# CONFIG_DRM_R128 is not set
1433# CONFIG_DRM_RADEON is not set
1434CONFIG_DRM_I810=y
1435# CONFIG_DRM_I830 is not set
1436CONFIG_DRM_I915=y
1437# CONFIG_DRM_MGA is not set
1438# CONFIG_DRM_SIS is not set
1439# CONFIG_DRM_VIA is not set
1440# CONFIG_DRM_SAVAGE is not set
1441CONFIG_VGASTATE=y
1442CONFIG_VIDEO_OUTPUT_CONTROL=y
1443CONFIG_FB=y
1444CONFIG_FIRMWARE_EDID=y
1445CONFIG_FB_DDC=y
1446CONFIG_FB_CFB_FILLRECT=y
1447CONFIG_FB_CFB_COPYAREA=y
1448CONFIG_FB_CFB_IMAGEBLIT=y
1449# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
1450# CONFIG_FB_SYS_FILLRECT is not set
1451# CONFIG_FB_SYS_COPYAREA is not set
1452# CONFIG_FB_SYS_IMAGEBLIT is not set
1453# CONFIG_FB_FOREIGN_ENDIAN is not set
1454# CONFIG_FB_SYS_FOPS is not set
1455# CONFIG_FB_SVGALIB is not set
1456# CONFIG_FB_MACMODES is not set
1457# CONFIG_FB_BACKLIGHT is not set
1458CONFIG_FB_MODE_HELPERS=y
1459# CONFIG_FB_TILEBLITTING is not set
1460
1461#
1462# Frame buffer hardware drivers
1463#
1464# CONFIG_FB_CIRRUS is not set
1465# CONFIG_FB_PM2 is not set
1466# CONFIG_FB_CYBER2000 is not set
1467# CONFIG_FB_ARC is not set
1468# CONFIG_FB_ASILIANT is not set
1469# CONFIG_FB_IMSTT is not set
1470CONFIG_FB_VGA16=y
1471CONFIG_FB_UVESA=y
1472CONFIG_FB_VESA=y
1473CONFIG_FB_EFI=y
1474# CONFIG_FB_N411 is not set
1475# CONFIG_FB_HGA is not set
1476# CONFIG_FB_S1D13XXX is not set
1477# CONFIG_FB_NVIDIA is not set
1478# CONFIG_FB_RIVA is not set
1479# CONFIG_FB_I810 is not set
1480# CONFIG_FB_LE80578 is not set
1481CONFIG_FB_INTEL=y
1482CONFIG_FB_INTEL_DEBUG=y
1483CONFIG_FB_INTEL_I2C=y
1484# CONFIG_FB_MATROX is not set
1485# CONFIG_FB_RADEON is not set
1486# CONFIG_FB_ATY128 is not set
1487# CONFIG_FB_ATY is not set
1488# CONFIG_FB_S3 is not set
1489# CONFIG_FB_SAVAGE is not set
1490# CONFIG_FB_SIS is not set
1491# CONFIG_FB_NEOMAGIC is not set
1492# CONFIG_FB_KYRO is not set
1493# CONFIG_FB_3DFX is not set
1494# CONFIG_FB_VOODOO1 is not set
1495# CONFIG_FB_VT8623 is not set
1496# CONFIG_FB_CYBLA is not set
1497# CONFIG_FB_TRIDENT is not set
1498# CONFIG_FB_ARK is not set
1499# CONFIG_FB_PM3 is not set
1500# CONFIG_FB_CARMINE is not set
1501# CONFIG_FB_GEODE is not set
1502# CONFIG_FB_VIRTUAL is not set
1503CONFIG_BACKLIGHT_LCD_SUPPORT=y
1504# CONFIG_LCD_CLASS_DEVICE is not set
1505CONFIG_BACKLIGHT_CLASS_DEVICE=y
1506# CONFIG_BACKLIGHT_CORGI is not set
1507# CONFIG_BACKLIGHT_PROGEAR is not set
1508CONFIG_BACKLIGHT_MBP_NVIDIA=y
1509
1510#
1511# Display device support
1512#
1513CONFIG_DISPLAY_SUPPORT=y
1514
1515#
1516# Display hardware drivers
1517#
1518
1519#
1520# Console display driver support
1521#
1522CONFIG_VGA_CONSOLE=y
1523CONFIG_VGACON_SOFT_SCROLLBACK=y
1524CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
1525CONFIG_VIDEO_SELECT=y
1526CONFIG_DUMMY_CONSOLE=y
1527CONFIG_FRAMEBUFFER_CONSOLE=y
1528# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1529# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1530# CONFIG_FONTS is not set
1531CONFIG_FONT_8x8=y
1532CONFIG_FONT_8x16=y
1533# CONFIG_LOGO is not set
1534CONFIG_SOUND=y
1535CONFIG_SND=y
1536CONFIG_SND_TIMER=y
1537CONFIG_SND_PCM=y
1538CONFIG_SND_HWDEP=y
1539CONFIG_SND_RAWMIDI=m
1540CONFIG_SND_SEQUENCER=y
1541CONFIG_SND_SEQ_DUMMY=y
1542# CONFIG_SND_MIXER_OSS is not set
1543# CONFIG_SND_PCM_OSS is not set
1544# CONFIG_SND_SEQUENCER_OSS is not set
1545CONFIG_SND_DYNAMIC_MINORS=y
1546# CONFIG_SND_SUPPORT_OLD_API is not set
1547CONFIG_SND_VERBOSE_PROCFS=y
1548CONFIG_SND_VERBOSE_PRINTK=y
1549CONFIG_SND_DEBUG=y
1550# CONFIG_SND_DEBUG_VERBOSE is not set
1551CONFIG_SND_PCM_XRUN_DEBUG=y
1552CONFIG_SND_VMASTER=y
1553CONFIG_SND_AC97_CODEC=y
1554CONFIG_SND_DRIVERS=y
1555# CONFIG_SND_PCSP is not set
1556# CONFIG_SND_DUMMY is not set
1557# CONFIG_SND_VIRMIDI is not set
1558# CONFIG_SND_MTPAV is not set
1559# CONFIG_SND_SERIAL_U16550 is not set
1560# CONFIG_SND_MPU401 is not set
1561CONFIG_SND_AC97_POWER_SAVE=y
1562CONFIG_SND_AC97_POWER_SAVE_DEFAULT=5
1563CONFIG_SND_PCI=y
1564# CONFIG_SND_AD1889 is not set
1565# CONFIG_SND_ALS300 is not set
1566# CONFIG_SND_ALS4000 is not set
1567# CONFIG_SND_ALI5451 is not set
1568# CONFIG_SND_ATIIXP is not set
1569# CONFIG_SND_ATIIXP_MODEM is not set
1570# CONFIG_SND_AU8810 is not set
1571# CONFIG_SND_AU8820 is not set
1572# CONFIG_SND_AU8830 is not set
1573# CONFIG_SND_AW2 is not set
1574# CONFIG_SND_AZT3328 is not set
1575# CONFIG_SND_BT87X is not set
1576# CONFIG_SND_CA0106 is not set
1577# CONFIG_SND_CMIPCI is not set
1578# CONFIG_SND_OXYGEN is not set
1579# CONFIG_SND_CS4281 is not set
1580# CONFIG_SND_CS46XX is not set
1581# CONFIG_SND_CS5530 is not set
1582# CONFIG_SND_CS5535AUDIO is not set
1583# CONFIG_SND_DARLA20 is not set
1584# CONFIG_SND_GINA20 is not set
1585# CONFIG_SND_LAYLA20 is not set
1586# CONFIG_SND_DARLA24 is not set
1587# CONFIG_SND_GINA24 is not set
1588# CONFIG_SND_LAYLA24 is not set
1589# CONFIG_SND_MONA is not set
1590# CONFIG_SND_MIA is not set
1591# CONFIG_SND_ECHO3G is not set
1592# CONFIG_SND_INDIGO is not set
1593# CONFIG_SND_INDIGOIO is not set
1594# CONFIG_SND_INDIGODJ is not set
1595# CONFIG_SND_EMU10K1 is not set
1596# CONFIG_SND_EMU10K1X is not set
1597# CONFIG_SND_ENS1370 is not set
1598# CONFIG_SND_ENS1371 is not set
1599# CONFIG_SND_ES1938 is not set
1600# CONFIG_SND_ES1968 is not set
1601# CONFIG_SND_FM801 is not set
1602CONFIG_SND_HDA_INTEL=y
1603CONFIG_SND_HDA_HWDEP=y
1604CONFIG_SND_HDA_CODEC_REALTEK=y
1605CONFIG_SND_HDA_CODEC_ANALOG=y
1606CONFIG_SND_HDA_CODEC_SIGMATEL=y
1607CONFIG_SND_HDA_CODEC_VIA=y
1608CONFIG_SND_HDA_CODEC_ATIHDMI=y
1609CONFIG_SND_HDA_CODEC_CONEXANT=y
1610CONFIG_SND_HDA_CODEC_CMEDIA=y
1611CONFIG_SND_HDA_CODEC_SI3054=y
1612CONFIG_SND_HDA_GENERIC=y
1613CONFIG_SND_HDA_POWER_SAVE=y
1614CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
1615# CONFIG_SND_HDSP is not set
1616# CONFIG_SND_HDSPM is not set
1617# CONFIG_SND_HIFIER is not set
1618# CONFIG_SND_ICE1712 is not set
1619# CONFIG_SND_ICE1724 is not set
1620CONFIG_SND_INTEL8X0=y
1621# CONFIG_SND_INTEL8X0M is not set
1622# CONFIG_SND_KORG1212 is not set
1623# CONFIG_SND_MAESTRO3 is not set
1624# CONFIG_SND_MIXART is not set
1625# CONFIG_SND_NM256 is not set
1626# CONFIG_SND_PCXHR is not set
1627# CONFIG_SND_RIPTIDE is not set
1628# CONFIG_SND_RME32 is not set
1629# CONFIG_SND_RME96 is not set
1630# CONFIG_SND_RME9652 is not set
1631# CONFIG_SND_SIS7019 is not set
1632# CONFIG_SND_SONICVIBES is not set
1633# CONFIG_SND_TRIDENT is not set
1634# CONFIG_SND_VIA82XX is not set
1635# CONFIG_SND_VIA82XX_MODEM is not set
1636# CONFIG_SND_VIRTUOSO is not set
1637# CONFIG_SND_VX222 is not set
1638# CONFIG_SND_YMFPCI is not set
1639CONFIG_SND_USB=y
1640CONFIG_SND_USB_AUDIO=m
1641CONFIG_SND_USB_USX2Y=m
1642CONFIG_SND_USB_CAIAQ=m
1643CONFIG_SND_USB_CAIAQ_INPUT=y
1644# CONFIG_SND_SOC is not set
1645# CONFIG_SOUND_PRIME is not set
1646CONFIG_AC97_BUS=y
1647CONFIG_HID_SUPPORT=y
1648CONFIG_HID=y
1649CONFIG_HID_DEBUG=y
1650CONFIG_HIDRAW=y
1651
1652#
1653# USB Input Devices
1654#
1655CONFIG_USB_HID=y
1656CONFIG_USB_HIDINPUT_POWERBOOK=y
1657CONFIG_HID_FF=y
1658CONFIG_HID_PID=y
1659CONFIG_LOGITECH_FF=y
1660# CONFIG_LOGIRUMBLEPAD2_FF is not set
1661CONFIG_PANTHERLORD_FF=y
1662CONFIG_THRUSTMASTER_FF=y
1663CONFIG_ZEROPLUS_FF=y
1664CONFIG_USB_HIDDEV=y
1665CONFIG_USB_SUPPORT=y
1666CONFIG_USB_ARCH_HAS_HCD=y
1667CONFIG_USB_ARCH_HAS_OHCI=y
1668CONFIG_USB_ARCH_HAS_EHCI=y
1669CONFIG_USB=y
1670# CONFIG_USB_DEBUG is not set
1671CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
1672
1673#
1674# Miscellaneous USB options
1675#
1676CONFIG_USB_DEVICEFS=y
1677# CONFIG_USB_DEVICE_CLASS is not set
1678# CONFIG_USB_DYNAMIC_MINORS is not set
1679CONFIG_USB_SUSPEND=y
1680# CONFIG_USB_OTG is not set
1681
1682#
1683# USB Host Controller Drivers
1684#
1685# CONFIG_USB_C67X00_HCD is not set
1686CONFIG_USB_EHCI_HCD=y
1687CONFIG_USB_EHCI_ROOT_HUB_TT=y
1688CONFIG_USB_EHCI_TT_NEWSCHED=y
1689CONFIG_USB_ISP116X_HCD=m
1690# CONFIG_USB_ISP1760_HCD is not set
1691CONFIG_USB_OHCI_HCD=y
1692# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
1693# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
1694CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1695CONFIG_USB_UHCI_HCD=y
1696CONFIG_USB_U132_HCD=m
1697CONFIG_USB_SL811_HCD=m
1698# CONFIG_USB_R8A66597_HCD is not set
1699
1700#
1701# USB Device Class drivers
1702#
1703CONFIG_USB_ACM=m
1704CONFIG_USB_PRINTER=m
1705# CONFIG_USB_WDM is not set
1706
1707#
1708# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1709#
1710
1711#
1712# may also be needed; see USB_STORAGE Help for more information
1713#
1714CONFIG_USB_STORAGE=y
1715# CONFIG_USB_STORAGE_DEBUG is not set
1716CONFIG_USB_STORAGE_DATAFAB=y
1717CONFIG_USB_STORAGE_FREECOM=y
1718CONFIG_USB_STORAGE_ISD200=y
1719CONFIG_USB_STORAGE_DPCM=y
1720CONFIG_USB_STORAGE_USBAT=y
1721CONFIG_USB_STORAGE_SDDR09=y
1722CONFIG_USB_STORAGE_SDDR55=y
1723CONFIG_USB_STORAGE_JUMPSHOT=y
1724CONFIG_USB_STORAGE_ALAUDA=y
1725# CONFIG_USB_STORAGE_ONETOUCH is not set
1726CONFIG_USB_STORAGE_KARMA=y
1727# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
1728# CONFIG_USB_LIBUSUAL is not set
1729
1730#
1731# USB Imaging devices
1732#
1733CONFIG_USB_MDC800=m
1734CONFIG_USB_MICROTEK=m
1735CONFIG_USB_MON=y
1736
1737#
1738# USB port drivers
1739#
1740CONFIG_USB_SERIAL=m
1741CONFIG_USB_EZUSB=y
1742CONFIG_USB_SERIAL_GENERIC=y
1743CONFIG_USB_SERIAL_AIRCABLE=m
1744CONFIG_USB_SERIAL_ARK3116=m
1745CONFIG_USB_SERIAL_BELKIN=m
1746CONFIG_USB_SERIAL_CH341=m
1747CONFIG_USB_SERIAL_WHITEHEAT=m
1748CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1749CONFIG_USB_SERIAL_CP2101=m
1750CONFIG_USB_SERIAL_CYPRESS_M8=m
1751CONFIG_USB_SERIAL_EMPEG=m
1752CONFIG_USB_SERIAL_FTDI_SIO=m
1753CONFIG_USB_SERIAL_FUNSOFT=m
1754CONFIG_USB_SERIAL_VISOR=m
1755CONFIG_USB_SERIAL_IPAQ=m
1756CONFIG_USB_SERIAL_IR=m
1757CONFIG_USB_SERIAL_EDGEPORT=m
1758CONFIG_USB_SERIAL_EDGEPORT_TI=m
1759CONFIG_USB_SERIAL_GARMIN=m
1760CONFIG_USB_SERIAL_IPW=m
1761CONFIG_USB_SERIAL_IUU=m
1762CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1763CONFIG_USB_SERIAL_KEYSPAN=m
1764CONFIG_USB_SERIAL_KEYSPAN_MPR=y
1765CONFIG_USB_SERIAL_KEYSPAN_USA28=y
1766CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
1767CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
1768CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
1769CONFIG_USB_SERIAL_KEYSPAN_USA19=y
1770CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
1771CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
1772CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
1773CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
1774CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
1775CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
1776CONFIG_USB_SERIAL_KLSI=m
1777CONFIG_USB_SERIAL_KOBIL_SCT=m
1778CONFIG_USB_SERIAL_MCT_U232=m
1779CONFIG_USB_SERIAL_MOS7720=m
1780CONFIG_USB_SERIAL_MOS7840=m
1781# CONFIG_USB_SERIAL_MOTOROLA is not set
1782CONFIG_USB_SERIAL_NAVMAN=m
1783CONFIG_USB_SERIAL_PL2303=m
1784CONFIG_USB_SERIAL_OTI6858=m
1785# CONFIG_USB_SERIAL_SPCP8X5 is not set
1786CONFIG_USB_SERIAL_HP4X=m
1787CONFIG_USB_SERIAL_SAFE=m
1788CONFIG_USB_SERIAL_SAFE_PADDED=y
1789CONFIG_USB_SERIAL_SIERRAWIRELESS=m
1790CONFIG_USB_SERIAL_TI=m
1791CONFIG_USB_SERIAL_CYBERJACK=m
1792CONFIG_USB_SERIAL_XIRCOM=m
1793CONFIG_USB_SERIAL_OPTION=m
1794CONFIG_USB_SERIAL_OMNINET=m
1795CONFIG_USB_SERIAL_DEBUG=m
1796
1797#
1798# USB Miscellaneous drivers
1799#
1800CONFIG_USB_EMI62=m
1801CONFIG_USB_EMI26=m
1802CONFIG_USB_ADUTUX=m
1803CONFIG_USB_AUERSWALD=m
1804# CONFIG_USB_RIO500 is not set
1805CONFIG_USB_LEGOTOWER=m
1806CONFIG_USB_LCD=m
1807CONFIG_USB_BERRY_CHARGE=m
1808CONFIG_USB_LED=m
1809# CONFIG_USB_CYPRESS_CY7C63 is not set
1810# CONFIG_USB_CYTHERM is not set
1811CONFIG_USB_PHIDGET=m
1812CONFIG_USB_PHIDGETKIT=m
1813CONFIG_USB_PHIDGETMOTORCONTROL=m
1814CONFIG_USB_PHIDGETSERVO=m
1815CONFIG_USB_IDMOUSE=m
1816CONFIG_USB_FTDI_ELAN=m
1817CONFIG_USB_APPLEDISPLAY=m
1818CONFIG_USB_SISUSBVGA=m
1819CONFIG_USB_SISUSBVGA_CON=y
1820CONFIG_USB_LD=m
1821CONFIG_USB_TRANCEVIBRATOR=m
1822CONFIG_USB_IOWARRIOR=m
1823# CONFIG_USB_TEST is not set
1824# CONFIG_USB_ISIGHTFW is not set
1825# CONFIG_USB_GADGET is not set
1826CONFIG_MMC=m
1827# CONFIG_MMC_DEBUG is not set
1828# CONFIG_MMC_UNSAFE_RESUME is not set
1829
1830#
1831# MMC/SD Card Drivers
1832#
1833CONFIG_MMC_BLOCK=m
1834CONFIG_MMC_BLOCK_BOUNCE=y
1835CONFIG_SDIO_UART=m
1836# CONFIG_MMC_TEST is not set
1837
1838#
1839# MMC/SD Host Controller Drivers
1840#
1841CONFIG_MMC_SDHCI=m
1842# CONFIG_MMC_SDHCI_PCI is not set
1843CONFIG_MMC_WBSD=m
1844CONFIG_MMC_TIFM_SD=m
1845CONFIG_MEMSTICK=m
1846CONFIG_MEMSTICK_DEBUG=y
1847
1848#
1849# MemoryStick drivers
1850#
1851# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
1852CONFIG_MSPRO_BLOCK=m
1853
1854#
1855# MemoryStick Host Controller Drivers
1856#
1857# CONFIG_MEMSTICK_TIFM_MS is not set
1858# CONFIG_MEMSTICK_JMICRON_38X is not set
1859CONFIG_NEW_LEDS=y
1860CONFIG_LEDS_CLASS=m
1861
1862#
1863# LED drivers
1864#
1865# CONFIG_LEDS_PCA9532 is not set
1866# CONFIG_LEDS_CLEVO_MAIL is not set
1867# CONFIG_LEDS_PCA955X is not set
1868
1869#
1870# LED Triggers
1871#
1872CONFIG_LEDS_TRIGGERS=y
1873# CONFIG_LEDS_TRIGGER_TIMER is not set
1874# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
1875# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
1876# CONFIG_ACCESSIBILITY is not set
1877# CONFIG_INFINIBAND is not set
1878# CONFIG_EDAC is not set
1879CONFIG_RTC_LIB=y
1880CONFIG_RTC_CLASS=y
1881# CONFIG_RTC_HCTOSYS is not set
1882# CONFIG_RTC_DEBUG is not set
1883
1884#
1885# RTC interfaces
1886#
1887CONFIG_RTC_INTF_SYSFS=y
1888CONFIG_RTC_INTF_PROC=y
1889CONFIG_RTC_INTF_DEV=y
1890# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1891# CONFIG_RTC_DRV_TEST is not set
1892
1893#
1894# I2C RTC drivers
1895#
1896# CONFIG_RTC_DRV_DS1307 is not set
1897# CONFIG_RTC_DRV_DS1374 is not set
1898# CONFIG_RTC_DRV_DS1672 is not set
1899# CONFIG_RTC_DRV_MAX6900 is not set
1900# CONFIG_RTC_DRV_RS5C372 is not set
1901# CONFIG_RTC_DRV_ISL1208 is not set
1902# CONFIG_RTC_DRV_X1205 is not set
1903# CONFIG_RTC_DRV_PCF8563 is not set
1904# CONFIG_RTC_DRV_PCF8583 is not set
1905# CONFIG_RTC_DRV_M41T80 is not set
1906# CONFIG_RTC_DRV_S35390A is not set
1907# CONFIG_RTC_DRV_FM3130 is not set
1908
1909#
1910# SPI RTC drivers
1911#
1912
1913#
1914# Platform RTC drivers
1915#
1916CONFIG_RTC_DRV_CMOS=y
1917# CONFIG_RTC_DRV_DS1511 is not set
1918# CONFIG_RTC_DRV_DS1553 is not set
1919# CONFIG_RTC_DRV_DS1742 is not set
1920# CONFIG_RTC_DRV_STK17TA8 is not set
1921# CONFIG_RTC_DRV_M48T86 is not set
1922# CONFIG_RTC_DRV_M48T59 is not set
1923# CONFIG_RTC_DRV_V3020 is not set
1924
1925#
1926# on-CPU RTC drivers
1927#
1928# CONFIG_DMADEVICES is not set
1929# CONFIG_UIO is not set
1930
1931#
1932# Firmware Drivers
1933#
1934# CONFIG_EDD is not set
1935CONFIG_FIRMWARE_MEMMAP=y
1936# CONFIG_DELL_RBU is not set
1937# CONFIG_DCDBAS is not set
1938# CONFIG_DMIID is not set
1939# CONFIG_ISCSI_IBFT_FIND is not set
1940
1941#
1942# File systems
1943#
1944# CONFIG_EXT2_FS is not set
1945CONFIG_EXT3_FS=y
1946CONFIG_EXT3_FS_XATTR=y
1947CONFIG_EXT3_FS_POSIX_ACL=y
1948CONFIG_EXT3_FS_SECURITY=y
1949# CONFIG_EXT4DEV_FS is not set
1950CONFIG_JBD=y
1951# CONFIG_JBD_DEBUG is not set
1952CONFIG_FS_MBCACHE=y
1953# CONFIG_REISERFS_FS is not set
1954# CONFIG_JFS_FS is not set
1955CONFIG_FS_POSIX_ACL=y
1956# CONFIG_XFS_FS is not set
1957# CONFIG_OCFS2_FS is not set
1958CONFIG_DNOTIFY=y
1959CONFIG_INOTIFY=y
1960CONFIG_INOTIFY_USER=y
1961CONFIG_QUOTA=y
1962CONFIG_QUOTA_NETLINK_INTERFACE=y
1963# CONFIG_PRINT_QUOTA_WARNING is not set
1964# CONFIG_QFMT_V1 is not set
1965CONFIG_QFMT_V2=y
1966CONFIG_QUOTACTL=y
1967# CONFIG_AUTOFS_FS is not set
1968# CONFIG_AUTOFS4_FS is not set
1969CONFIG_FUSE_FS=m
1970CONFIG_GENERIC_ACL=y
1971
1972#
1973# CD-ROM/DVD Filesystems
1974#
1975CONFIG_ISO9660_FS=y
1976CONFIG_JOLIET=y
1977CONFIG_ZISOFS=y
1978CONFIG_UDF_FS=m
1979CONFIG_UDF_NLS=y
1980
1981#
1982# DOS/FAT/NT Filesystems
1983#
1984CONFIG_FAT_FS=y
1985CONFIG_MSDOS_FS=y
1986CONFIG_VFAT_FS=y
1987CONFIG_FAT_DEFAULT_CODEPAGE=437
1988CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
1989# CONFIG_NTFS_FS is not set
1990
1991#
1992# Pseudo filesystems
1993#
1994CONFIG_PROC_FS=y
1995CONFIG_PROC_KCORE=y
1996CONFIG_PROC_VMCORE=y
1997CONFIG_PROC_SYSCTL=y
1998CONFIG_SYSFS=y
1999CONFIG_TMPFS=y
2000CONFIG_TMPFS_POSIX_ACL=y
2001CONFIG_HUGETLBFS=y
2002CONFIG_HUGETLB_PAGE=y
2003CONFIG_CONFIGFS_FS=m
2004
2005#
2006# Layered filesystems
2007#
2008# CONFIG_ECRYPT_FS is not set
2009CONFIG_UNION_FS=y
2010# CONFIG_UNION_FS_XATTR is not set
2011# CONFIG_UNION_FS_DEBUG is not set
2012
2013#
2014# Miscellaneous filesystems
2015#
2016# CONFIG_ADFS_FS is not set
2017# CONFIG_AFFS_FS is not set
2018# CONFIG_HFS_FS is not set
2019# CONFIG_HFSPLUS_FS is not set
2020# CONFIG_BEFS_FS is not set
2021# CONFIG_BFS_FS is not set
2022# CONFIG_EFS_FS is not set
2023# CONFIG_CRAMFS is not set
2024CONFIG_SQUASHFS=y
2025# CONFIG_SQUASHFS_EMBEDDED is not set
2026CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
2027# CONFIG_VXFS_FS is not set
2028# CONFIG_MINIX_FS is not set
2029# CONFIG_OMFS_FS is not set
2030# CONFIG_HPFS_FS is not set
2031# CONFIG_QNX4FS_FS is not set
2032# CONFIG_ROMFS_FS is not set
2033# CONFIG_SYSV_FS is not set
2034# CONFIG_UFS_FS is not set
2035CONFIG_NETWORK_FILESYSTEMS=y
2036# CONFIG_NFS_FS is not set
2037# CONFIG_NFSD is not set
2038# CONFIG_SMB_FS is not set
2039# CONFIG_CIFS is not set
2040# CONFIG_NCP_FS is not set
2041# CONFIG_CODA_FS is not set
2042# CONFIG_AFS_FS is not set
2043
2044#
2045# Partition Types
2046#
2047CONFIG_PARTITION_ADVANCED=y
2048# CONFIG_ACORN_PARTITION is not set
2049CONFIG_OSF_PARTITION=y
2050CONFIG_AMIGA_PARTITION=y
2051# CONFIG_ATARI_PARTITION is not set
2052CONFIG_MAC_PARTITION=y
2053CONFIG_MSDOS_PARTITION=y
2054CONFIG_BSD_DISKLABEL=y
2055CONFIG_MINIX_SUBPARTITION=y
2056CONFIG_SOLARIS_X86_PARTITION=y
2057CONFIG_UNIXWARE_DISKLABEL=y
2058# CONFIG_LDM_PARTITION is not set
2059CONFIG_SGI_PARTITION=y
2060# CONFIG_ULTRIX_PARTITION is not set
2061CONFIG_SUN_PARTITION=y
2062CONFIG_KARMA_PARTITION=y
2063CONFIG_EFI_PARTITION=y
2064# CONFIG_SYSV68_PARTITION is not set
2065CONFIG_NLS=y
2066CONFIG_NLS_DEFAULT="utf8"
2067CONFIG_NLS_CODEPAGE_437=y
2068CONFIG_NLS_CODEPAGE_737=m
2069CONFIG_NLS_CODEPAGE_775=m
2070CONFIG_NLS_CODEPAGE_850=m
2071CONFIG_NLS_CODEPAGE_852=m
2072CONFIG_NLS_CODEPAGE_855=m
2073CONFIG_NLS_CODEPAGE_857=m
2074CONFIG_NLS_CODEPAGE_860=m
2075CONFIG_NLS_CODEPAGE_861=m
2076CONFIG_NLS_CODEPAGE_862=m
2077CONFIG_NLS_CODEPAGE_863=m
2078CONFIG_NLS_CODEPAGE_864=m
2079CONFIG_NLS_CODEPAGE_865=m
2080CONFIG_NLS_CODEPAGE_866=m
2081CONFIG_NLS_CODEPAGE_869=m
2082CONFIG_NLS_CODEPAGE_936=m
2083CONFIG_NLS_CODEPAGE_950=m
2084CONFIG_NLS_CODEPAGE_932=m
2085CONFIG_NLS_CODEPAGE_949=m
2086CONFIG_NLS_CODEPAGE_874=m
2087CONFIG_NLS_ISO8859_8=m
2088CONFIG_NLS_CODEPAGE_1250=m
2089CONFIG_NLS_CODEPAGE_1251=m
2090CONFIG_NLS_ASCII=y
2091CONFIG_NLS_ISO8859_1=m
2092CONFIG_NLS_ISO8859_2=m
2093CONFIG_NLS_ISO8859_3=m
2094CONFIG_NLS_ISO8859_4=m
2095CONFIG_NLS_ISO8859_5=m
2096CONFIG_NLS_ISO8859_6=m
2097CONFIG_NLS_ISO8859_7=m
2098CONFIG_NLS_ISO8859_9=m
2099CONFIG_NLS_ISO8859_13=m
2100CONFIG_NLS_ISO8859_14=m
2101CONFIG_NLS_ISO8859_15=m
2102CONFIG_NLS_KOI8_R=m
2103CONFIG_NLS_KOI8_U=m
2104CONFIG_NLS_UTF8=m
2105# CONFIG_DLM is not set
2106
2107#
2108# Kernel hacking
2109#
2110CONFIG_TRACE_IRQFLAGS_SUPPORT=y
2111CONFIG_PRINTK_TIME=y
2112# CONFIG_ENABLE_WARN_DEPRECATED is not set
2113CONFIG_ENABLE_MUST_CHECK=y
2114CONFIG_FRAME_WARN=1024
2115CONFIG_MAGIC_SYSRQ=y
2116CONFIG_UNUSED_SYMBOLS=y
2117CONFIG_DEBUG_FS=y
2118# CONFIG_HEADERS_CHECK is not set
2119CONFIG_DEBUG_KERNEL=y
2120CONFIG_DEBUG_SHIRQ=y
2121CONFIG_DETECT_SOFTLOCKUP=y
2122# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
2123CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
2124CONFIG_SCHED_DEBUG=y
2125CONFIG_SCHEDSTATS=y
2126CONFIG_TIMER_STATS=y
2127# CONFIG_DEBUG_OBJECTS is not set
2128# CONFIG_DEBUG_SLAB is not set
2129# CONFIG_DEBUG_RT_MUTEXES is not set
2130# CONFIG_RT_MUTEX_TESTER is not set
2131# CONFIG_DEBUG_SPINLOCK is not set
2132# CONFIG_DEBUG_MUTEXES is not set
2133# CONFIG_DEBUG_LOCK_ALLOC is not set
2134# CONFIG_PROVE_LOCKING is not set
2135# CONFIG_LOCK_STAT is not set
2136CONFIG_DEBUG_SPINLOCK_SLEEP=y
2137# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
2138CONFIG_STACKTRACE=y
2139# CONFIG_DEBUG_KOBJECT is not set
2140# CONFIG_DEBUG_HIGHMEM is not set
2141CONFIG_DEBUG_BUGVERBOSE=y
2142CONFIG_DEBUG_INFO=y
2143# CONFIG_DEBUG_VM is not set
2144# CONFIG_DEBUG_WRITECOUNT is not set
2145CONFIG_DEBUG_MEMORY_INIT=y
2146CONFIG_DEBUG_LIST=y
2147# CONFIG_DEBUG_SG is not set
2148CONFIG_FRAME_POINTER=y
2149CONFIG_BOOT_PRINTK_DELAY=y
2150# CONFIG_RCU_TORTURE_TEST is not set
2151# CONFIG_BACKTRACE_SELF_TEST is not set
2152# CONFIG_FAULT_INJECTION is not set
2153CONFIG_LATENCYTOP=y
2154CONFIG_HAVE_FTRACE=y
2155CONFIG_HAVE_DYNAMIC_FTRACE=y
2156CONFIG_TRACING=y
2157# CONFIG_FTRACE is not set
2158# CONFIG_IRQSOFF_TRACER is not set
2159CONFIG_SYSPROF_TRACER=y
2160# CONFIG_SCHED_TRACER is not set
2161# CONFIG_CONTEXT_SWITCH_TRACER is not set
2162# CONFIG_FTRACE_STARTUP_TEST is not set
2163# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
2164# CONFIG_SAMPLES is not set
2165CONFIG_HAVE_ARCH_KGDB=y
2166# CONFIG_KGDB is not set
2167# CONFIG_STRICT_DEVMEM is not set
2168CONFIG_X86_VERBOSE_BOOTUP=y
2169CONFIG_EARLY_PRINTK=y
2170# CONFIG_DEBUG_STACKOVERFLOW is not set
2171# CONFIG_DEBUG_STACK_USAGE is not set
2172# CONFIG_DEBUG_PAGEALLOC is not set
2173# CONFIG_DEBUG_PER_CPU_MAPS is not set
2174CONFIG_X86_PTDUMP=y
2175CONFIG_DEBUG_RODATA=y
2176# CONFIG_DEBUG_RODATA_TEST is not set
2177# CONFIG_DEBUG_NX_TEST is not set
2178# CONFIG_4KSTACKS is not set
2179CONFIG_DOUBLEFAULT=y
2180# CONFIG_MMIOTRACE is not set
2181CONFIG_IO_DELAY_TYPE_0X80=0
2182CONFIG_IO_DELAY_TYPE_0XED=1
2183CONFIG_IO_DELAY_TYPE_UDELAY=2
2184CONFIG_IO_DELAY_TYPE_NONE=3
2185CONFIG_IO_DELAY_0X80=y
2186# CONFIG_IO_DELAY_0XED is not set
2187# CONFIG_IO_DELAY_UDELAY is not set
2188# CONFIG_IO_DELAY_NONE is not set
2189CONFIG_DEFAULT_IO_DELAY_TYPE=0
2190CONFIG_DEBUG_BOOT_PARAMS=y
2191# CONFIG_CPA_DEBUG is not set
2192# CONFIG_OPTIMIZE_INLINING is not set
2193
2194#
2195# Security options
2196#
2197CONFIG_KEYS=y
2198CONFIG_KEYS_DEBUG_PROC_KEYS=y
2199CONFIG_SECURITY=y
2200CONFIG_SECURITY_NETWORK=y
2201CONFIG_SECURITY_NETWORK_XFRM=y
2202CONFIG_SECURITY_FILE_CAPABILITIES=y
2203# CONFIG_SECURITY_ROOTPLUG is not set
2204CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536
2205# CONFIG_SECURITY_SELINUX is not set
2206# CONFIG_SECURITY_SMACK is not set
2207CONFIG_CRYPTO=y
2208
2209#
2210# Crypto core or helper
2211#
2212CONFIG_CRYPTO_ALGAPI=y
2213CONFIG_CRYPTO_AEAD=m
2214CONFIG_CRYPTO_BLKCIPHER=m
2215CONFIG_CRYPTO_HASH=y
2216CONFIG_CRYPTO_MANAGER=y
2217CONFIG_CRYPTO_GF128MUL=m
2218CONFIG_CRYPTO_NULL=m
2219# CONFIG_CRYPTO_CRYPTD is not set
2220CONFIG_CRYPTO_AUTHENC=m
2221CONFIG_CRYPTO_TEST=m
2222
2223#
2224# Authenticated Encryption with Associated Data
2225#
2226CONFIG_CRYPTO_CCM=m
2227CONFIG_CRYPTO_GCM=m
2228CONFIG_CRYPTO_SEQIV=m
2229
2230#
2231# Block modes
2232#
2233CONFIG_CRYPTO_CBC=m
2234CONFIG_CRYPTO_CTR=m
2235# CONFIG_CRYPTO_CTS is not set
2236CONFIG_CRYPTO_ECB=m
2237CONFIG_CRYPTO_LRW=m
2238CONFIG_CRYPTO_PCBC=m
2239CONFIG_CRYPTO_XTS=m
2240
2241#
2242# Hash modes
2243#
2244CONFIG_CRYPTO_HMAC=y
2245CONFIG_CRYPTO_XCBC=m
2246
2247#
2248# Digest
2249#
2250CONFIG_CRYPTO_CRC32C=m
2251CONFIG_CRYPTO_MD4=m
2252CONFIG_CRYPTO_MD5=y
2253CONFIG_CRYPTO_MICHAEL_MIC=m
2254# CONFIG_CRYPTO_RMD128 is not set
2255# CONFIG_CRYPTO_RMD160 is not set
2256# CONFIG_CRYPTO_RMD256 is not set
2257# CONFIG_CRYPTO_RMD320 is not set
2258CONFIG_CRYPTO_SHA1=y
2259CONFIG_CRYPTO_SHA256=m
2260CONFIG_CRYPTO_SHA512=m
2261CONFIG_CRYPTO_TGR192=m
2262CONFIG_CRYPTO_WP512=m
2263
2264#
2265# Ciphers
2266#
2267CONFIG_CRYPTO_AES=m
2268# CONFIG_CRYPTO_AES_586 is not set
2269CONFIG_CRYPTO_ANUBIS=m
2270CONFIG_CRYPTO_ARC4=m
2271CONFIG_CRYPTO_BLOWFISH=m
2272CONFIG_CRYPTO_CAMELLIA=m
2273CONFIG_CRYPTO_CAST5=m
2274CONFIG_CRYPTO_CAST6=m
2275CONFIG_CRYPTO_DES=m
2276CONFIG_CRYPTO_FCRYPT=m
2277CONFIG_CRYPTO_KHAZAD=m
2278CONFIG_CRYPTO_SALSA20=m
2279# CONFIG_CRYPTO_SALSA20_586 is not set
2280CONFIG_CRYPTO_SEED=m
2281CONFIG_CRYPTO_SERPENT=m
2282CONFIG_CRYPTO_TEA=m
2283CONFIG_CRYPTO_TWOFISH=m
2284CONFIG_CRYPTO_TWOFISH_COMMON=m
2285# CONFIG_CRYPTO_TWOFISH_586 is not set
2286
2287#
2288# Compression
2289#
2290CONFIG_CRYPTO_DEFLATE=m
2291# CONFIG_CRYPTO_LZO is not set
2292CONFIG_CRYPTO_HW=y
2293# CONFIG_CRYPTO_DEV_PADLOCK is not set
2294# CONFIG_CRYPTO_DEV_GEODE is not set
2295# CONFIG_CRYPTO_DEV_HIFN_795X is not set
2296CONFIG_HAVE_KVM=y
2297# CONFIG_VIRTUALIZATION is not set
2298
2299#
2300# Library routines
2301#
2302CONFIG_BITREVERSE=y
2303CONFIG_GENERIC_FIND_FIRST_BIT=y
2304CONFIG_GENERIC_FIND_NEXT_BIT=y
2305CONFIG_CRC_CCITT=m
2306CONFIG_CRC16=m
2307CONFIG_CRC_T10DIF=y
2308CONFIG_CRC_ITU_T=m
2309CONFIG_CRC32=y
2310# CONFIG_CRC7 is not set
2311CONFIG_LIBCRC32C=m
2312CONFIG_AUDIT_GENERIC=y
2313CONFIG_ZLIB_INFLATE=y
2314CONFIG_ZLIB_DEFLATE=m
2315CONFIG_TEXTSEARCH=y
2316CONFIG_TEXTSEARCH_KMP=m
2317CONFIG_TEXTSEARCH_BM=m
2318CONFIG_TEXTSEARCH_FSM=m
2319CONFIG_PLIST=y
2320CONFIG_HAS_IOMEM=y
2321CONFIG_HAS_IOPORT=y
2322CONFIG_HAS_DMA=y
diff --git a/meta/packages/linux/linux-moblin2.inc b/meta/packages/linux/linux-moblin2.inc
new file mode 100644
index 0000000000..802bde26ee
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2.inc
@@ -0,0 +1,18 @@
1DESCRIPTION = "2.6 Linux Development Kernel for moblin2 platforms"
2SECTION = "kernel"
3LICENSE = "GPL"
4
5inherit kernel
6
7do_configure() {
8
9 rm -f ${S}/.config || true
10
11 cp ${WORKDIR}/defconfig-${MACHINE} ${S}/.config
12
13 yes '' | oe_runmake oldconfig
14
15}
16
17
18COMPATIBLE_MACHINE = "eee901" \ No newline at end of file
diff --git a/meta/packages/linux/linux-moblin2_2.6.27-rc1.bb b/meta/packages/linux/linux-moblin2_2.6.27-rc1.bb
new file mode 100644
index 0000000000..9e457607a2
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2_2.6.27-rc1.bb
@@ -0,0 +1,23 @@
1require linux-moblin2.inc
2
3PR = "r0"
4
5DEFAULT_PREFERENCE_eee901 = "1"
6
7SRC_URI = "${KERNELORG_MIRROR}pub/linux/kernel/v2.6/linux-2.6.26.tar.bz2 \
8 ${KERNELORG_MIRROR}pub/linux/kernel/v2.6/testing/patch-2.6.27-rc1.bz2;patch=1 \
9 file://0001_Export_shmem_file_setup_for_DRM-GEM.patch;patch=1 \
10 file://0002_i915.Use_more_consistent_names_for_regs.patch;patch=1 \
11 file://0003_i915.Add_support_for_MSI_and_interrupt_mitigation.patch;patch=1 \
12 file://0004_i915.Track_progress_inside_of_batchbuffers_for_determining_wedgedness.patch;patch=1 \
13 file://0005_i915.remove_settable_use_mi_batchbuffer_start.patch;patch=1 \
14 file://0006_i915.Ignore_X_server_provided_mmio_address.patch;patch=1 \
15 file://0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch;patch=1 \
16 file://0008_drm.Add_GEM_graphics_execution_manager_to_i915_driver.patch;patch=1 \
17 file://0009-squashfs3.3-2.6.27.patch;patch=1 \
18 file://0010_unionfs-2.4_for_2.6.27-rc1.patch;patch=1 \
19 file://0011_workaround_unidef_step.patch;patch=1 \
20 file://0012_intelfb_945gme.patch;patch=1 \
21 file://defconfig-eee901"
22
23S = "${WORKDIR}/linux-2.6.26" \ No newline at end of file