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 spin_unlock(&lli->lli_lock);
58 void ll_open_complete(struct inode *inode)
60 struct ll_inode_info *lli = ll_i2info(inode);
61 spin_lock(&lli->lli_lock);
62 lli->lli_send_done_writing = 0;
63 spin_unlock(&lli->lli_lock);
66 /* if we close with writes in flight then we want the completion or cancelation
67 * of those writes to send a DONE_WRITING rpc to the MDS */
68 int ll_is_inode_dirty(struct inode *inode)
70 struct ll_inode_info *lli = ll_i2info(inode);
74 spin_lock(&lli->lli_lock);
75 if (!list_empty(&lli->lli_pending_write_llaps))
77 spin_unlock(&lli->lli_lock);
81 void ll_try_done_writing(struct inode *inode)
83 struct ll_inode_info *lli = ll_i2info(inode);
84 struct ll_close_queue *lcq = ll_i2sbi(inode)->ll_lcq;
87 spin_lock(&lli->lli_lock);
89 if (lli->lli_send_done_writing &&
90 list_empty(&lli->lli_pending_write_llaps)) {
91 spin_lock(&lcq->lcq_lock);
92 if (list_empty(&lli->lli_close_item)) {
93 CDEBUG(D_INODE, "adding inode %lu/%u to close list\n",
94 inode->i_ino, inode->i_generation);
95 list_add_tail(&lli->lli_close_item, &lcq->lcq_list);
96 wake_up(&lcq->lcq_waitq);
99 spin_unlock(&lcq->lcq_lock);
102 spin_unlock(&lli->lli_lock);
105 * we can't grab inode under lli_lock, because:
106 * ll_try_done_writing: ll_prep_inode:
107 * spin_lock(&lli_lock) spin_lock(&inode_lock)
108 * igrab() ll_update_inode()
109 * spin_lock(&inode_lock) spin_lock(&lli_lock)
112 LASSERT(igrab(inode) == inode);
115 /* The MDS needs us to get the real file attributes, then send a DONE_WRITING */
116 void ll_queue_done_writing(struct inode *inode)
118 struct ll_inode_info *lli = ll_i2info(inode);
121 CDEBUG(D_INODE, "queue closing for %lu/%u\n",
122 inode->i_ino, inode->i_generation);
123 spin_lock(&lli->lli_lock);
124 lli->lli_send_done_writing = 1;
125 spin_unlock(&lli->lli_lock);
127 ll_try_done_writing(inode);
131 /* If we know the file size and have the cookies:
132 * - send a DONE_WRITING rpc
135 * - get a whole-file lock
136 * - get the authoritative size and all cookies with GETATTRs
137 * - send a DONE_WRITING rpc
139 static void ll_try_to_close(struct inode *inode)
141 struct ll_sb_info *sbi = ll_i2sbi(inode);
142 ll_md_real_close(sbi->ll_md_exp, inode, FMODE_WRITE | FMODE_SYNC);
145 static struct ll_inode_info *ll_close_next_lli(struct ll_close_queue *lcq)
147 struct ll_inode_info *lli = NULL;
149 spin_lock(&lcq->lcq_lock);
151 if (lcq->lcq_list.next == NULL)
153 else if (!list_empty(&lcq->lcq_list)) {
154 lli = list_entry(lcq->lcq_list.next, struct ll_inode_info,
156 list_del_init(&lli->lli_close_item);
159 spin_unlock(&lcq->lcq_lock);
163 static int ll_close_thread(void *arg)
165 struct ll_close_queue *lcq = arg;
168 /* XXX boiler-plate */
170 char name[sizeof(current->comm)];
172 snprintf(name, sizeof(name) - 1, "ll_close");
173 kportal_daemonize(name);
174 SIGNAL_MASK_LOCK(current, flags);
175 sigfillset(¤t->blocked);
177 SIGNAL_MASK_UNLOCK(current, flags);
180 complete(&lcq->lcq_comp);
183 struct l_wait_info lwi = { 0 };
184 struct ll_inode_info *lli;
187 l_wait_event_exclusive(lcq->lcq_waitq,
188 (lli = ll_close_next_lli(lcq)) != NULL,
193 inode = ll_info2i(lli);
194 ll_try_to_close(inode);
200 /* SMF-safe way to finish threads */
201 complete_and_exit(&lcq->lcq_comp, 0);
204 int ll_close_thread_start(struct ll_close_queue **lcq_ret)
206 struct ll_close_queue *lcq;
209 OBD_ALLOC(lcq, sizeof(*lcq));
213 spin_lock_init(&lcq->lcq_lock);
214 INIT_LIST_HEAD(&lcq->lcq_list);
215 init_waitqueue_head(&lcq->lcq_waitq);
216 init_completion(&lcq->lcq_comp);
218 pid = kernel_thread(ll_close_thread, lcq, 0);
220 OBD_FREE(lcq, sizeof(*lcq));
224 wait_for_completion(&lcq->lcq_comp);
229 void ll_close_thread_stop(struct ll_close_queue *lcq)
231 init_completion(&lcq->lcq_comp);
232 lcq->lcq_list.next = NULL;
233 wake_up(&lcq->lcq_waitq);
234 wait_for_completion(&lcq->lcq_comp);
235 OBD_FREE(lcq, sizeof(*lcq));