1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Lustre Lite routines to issue a secondary close after writeback
6 * Copyright (c) 2001-2003 Cluster File Systems, Inc.
8 * This file is part of Lustre, http://www.lustre.org.
10 * Lustre is free software; you can redistribute it and/or
11 * modify it under the terms of version 2 of the GNU General Public
12 * License as published by the Free Software Foundation.
14 * Lustre is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with Lustre; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <linux/module.h>
26 #define DEBUG_SUBSYSTEM S_LLITE
28 #include <linux/lustre_mds.h>
29 #include <linux/lustre_lite.h>
30 #include <linux/lustre_gs.h>
31 #include "llite_internal.h"
33 /* record that a write is in flight */
34 void llap_write_pending(struct inode *inode, struct ll_async_page *llap)
36 struct ll_inode_info *lli = ll_i2info(inode);
37 struct page *page = llap->llap_page;
38 spin_lock(&lli->lli_lock);
39 CDEBUG(D_INODE, "track page 0x%p/%lu %s\n",
40 page, (unsigned long) page->index,
41 !list_empty(&llap->llap_pending_write) ? "(already)" : "");
42 if (list_empty(&llap->llap_pending_write))
43 list_add(&llap->llap_pending_write,
44 &lli->lli_pending_write_llaps);
45 spin_unlock(&lli->lli_lock);
48 /* record that a write has completed */
49 void llap_write_complete(struct inode *inode, struct ll_async_page *llap)
51 struct ll_inode_info *lli = ll_i2info(inode);
52 spin_lock(&lli->lli_lock);
53 if (!list_empty(&llap->llap_pending_write))
54 list_del_init(&llap->llap_pending_write);
55 if (list_empty(&lli->lli_pending_write_llaps))
56 wake_up(&lli->lli_dirty_wait);
57 spin_unlock(&lli->lli_lock);
60 void ll_open_complete(struct inode *inode)
62 struct ll_inode_info *lli = ll_i2info(inode);
63 spin_lock(&lli->lli_lock);
64 lli->lli_send_done_writing = 0;
65 spin_unlock(&lli->lli_lock);
68 /* if we close with writes in flight then we want the completion or cancelation
69 * of those writes to send a DONE_WRITING rpc to the MDS */
70 int ll_is_inode_dirty(struct inode *inode)
72 struct ll_inode_info *lli = ll_i2info(inode);
76 spin_lock(&lli->lli_lock);
77 if (!list_empty(&lli->lli_pending_write_llaps))
79 spin_unlock(&lli->lli_lock);
83 void ll_try_done_writing(struct inode *inode)
85 struct ll_inode_info *lli = ll_i2info(inode);
86 struct ll_close_queue *lcq = ll_i2sbi(inode)->ll_lcq;
89 spin_lock(&lli->lli_lock);
91 if (lli->lli_send_done_writing &&
92 list_empty(&lli->lli_pending_write_llaps)) {
93 spin_lock(&lcq->lcq_lock);
94 if (list_empty(&lli->lli_close_item)) {
95 CDEBUG(D_INODE, "adding inode %lu/%u to close list\n",
96 inode->i_ino, inode->i_generation);
97 list_add_tail(&lli->lli_close_item, &lcq->lcq_list);
98 wake_up(&lcq->lcq_waitq);
101 spin_unlock(&lcq->lcq_lock);
104 spin_unlock(&lli->lli_lock);
107 * we can't grab inode under lli_lock, because:
108 * ll_try_done_writing: ll_prep_inode:
109 * spin_lock(&lli_lock) spin_lock(&inode_lock)
110 * igrab() ll_update_inode()
111 * spin_lock(&inode_lock) spin_lock(&lli_lock)
114 LASSERT(igrab(inode) == inode);
117 /* The MDS needs us to get the real file attributes, then send a DONE_WRITING */
118 void ll_queue_done_writing(struct inode *inode)
120 struct ll_inode_info *lli = ll_i2info(inode);
123 CDEBUG(D_INODE, "queue closing for %lu/%u\n",
124 inode->i_ino, inode->i_generation);
125 spin_lock(&lli->lli_lock);
126 lli->lli_send_done_writing = 1;
127 spin_unlock(&lli->lli_lock);
129 ll_try_done_writing(inode);
133 /* If we know the file size and have the cookies:
134 * - send a DONE_WRITING rpc
137 * - get a whole-file lock
138 * - get the authoritative size and all cookies with GETATTRs
139 * - send a DONE_WRITING rpc
141 static void ll_try_to_close(struct inode *inode)
143 struct ll_sb_info *sbi = ll_i2sbi(inode);
144 ll_md_real_close(sbi->ll_md_exp, inode, FMODE_WRITE | FMODE_SYNC);
147 static struct ll_inode_info *ll_close_next_lli(struct ll_close_queue *lcq)
149 struct ll_inode_info *lli = NULL;
151 spin_lock(&lcq->lcq_lock);
153 /* first, check for queued request. otherwise, we would
154 * leak them upon umount */
155 if (!list_empty(&lcq->lcq_list)) {
156 lli = list_entry(lcq->lcq_list.next, struct ll_inode_info,
158 list_del_init(&lli->lli_close_item);
159 } else if (lcq->lcq_stop != 0) {
163 spin_unlock(&lcq->lcq_lock);
167 static int ll_close_thread(void *arg)
169 struct ll_close_queue *lcq = arg;
172 /* XXX boiler-plate */
174 char name[sizeof(current->comm)];
176 snprintf(name, sizeof(name) - 1, "ll_close");
177 kportal_daemonize(name);
178 SIGNAL_MASK_LOCK(current, flags);
179 sigfillset(¤t->blocked);
181 SIGNAL_MASK_UNLOCK(current, flags);
184 complete(&lcq->lcq_comp);
187 struct l_wait_info lwi = { 0 };
188 struct ll_inode_info *lli;
191 l_wait_event_exclusive(lcq->lcq_waitq,
192 (lli = ll_close_next_lli(lcq)) != NULL,
197 inode = ll_info2i(lli);
198 ll_try_to_close(inode);
204 /* SMF-safe way to finish threads */
205 complete_and_exit(&lcq->lcq_comp, 0);
208 int ll_close_thread_start(struct ll_close_queue **lcq_ret)
210 struct ll_close_queue *lcq;
213 OBD_ALLOC(lcq, sizeof(*lcq));
218 spin_lock_init(&lcq->lcq_lock);
219 INIT_LIST_HEAD(&lcq->lcq_list);
220 init_waitqueue_head(&lcq->lcq_waitq);
221 init_completion(&lcq->lcq_comp);
223 pid = kernel_thread(ll_close_thread, lcq, 0);
225 OBD_FREE(lcq, sizeof(*lcq));
229 wait_for_completion(&lcq->lcq_comp);
234 void ll_close_thread_stop(struct ll_close_queue *lcq)
236 init_completion(&lcq->lcq_comp);
238 wake_up(&lcq->lcq_waitq);
239 wait_for_completion(&lcq->lcq_comp);
240 OBD_FREE(lcq, sizeof(*lcq));